В python можно делать:
foo = {} assert foo.get('bar', 'baz') == 'baz'
В PHP можно использовать триниверс, как в:
$foo = array(); assert( (isset($foo['bar'])) ? $foo['bar'] : 'baz' == 'baz');
Я ищу версию для гольфа. Могу ли я сделать это короче / лучше в PHP?
Я просто придумал эту небольшую вспомогательную функцию:
function get(&$var, $default=null) { return isset($var) ? $var : $default; }
Это не только работает для словарей, но и для всех переменных:
$test = array('foo'=>'bar'); get($test['foo'],'nope'); // bar get($test['baz'],'nope'); // nope get($test['spam']['eggs'],'nope'); // nope get($undefined,'nope'); // nope
Передача ранее не заданной переменной для каждой ссылки не вызывает ошибку NOTICE
. Вместо этого передача $var
по ссылке определит его и установит для него значение null
. Значение по умолчанию также будет возвращено, если переданная переменная равна null
. Также обратите внимание на неявно сгенерированный массив в примере спама / яйца:
json_encode($test); // {"foo":"bar","baz":null,"spam":{"eggs":null}} $undefined===null; // true (got defined by passing it to get) isset($undefined) // false get($undefined,'nope'); // nope
Обратите внимание, что хотя $var
передается по ссылке, результат get($var)
будет копией $var
, а не ссылкой. Надеюсь, это поможет!
Проходит время, и PHP развивается. PHP7 теперь поддерживает Null-коалесцирующий оператор :
// Fetches the value of $_GET['user'] and returns 'nobody' // if it does not exist. $username = $_GET['user'] ?? 'nobody'; // This is equivalent to: $username = isset($_GET['user']) ? $_GET['user'] : 'nobody'; // Coalescing can be chained: this will return the first // defined value out of $_GET['user'], $_POST['user'], and // 'nobody'. $username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
использовать оператор управления ошибкой @ с помощью PHP 5.3 ярлыка версии тройного оператора
$bar = @$foo['bar'] ?: 'defaultvalue';
PHP 5.3 имеет сокращенную версию троичного оператора:
$x = $foo ?: 'defaultvaluehere';
который в основном
if (isset($foo)) { $x = $foo; else { $x = 'defaultvaluehere'; }
В противном случае нет, нет более короткого метода.
Мне полезно создать такую функцию:
function array_value($array, $key, $default_value = null) { return is_array($array) && array_key_exists($key, $array) ? $array[$key] : $default_value; }
И используйте его вот так:
$params = array('code' => 7777, 'name' => "Cloud Strife"); $code = array_value($params, 'code'); $name = array_value($params, 'name'); $weapon = array_value($params, 'weapon', "Buster Sword"); $materia = array_value($params, 'materia'); echo "{ code: $code, name: $name, weapon: $weapon, materia: $materia }";
Значение по умолчанию в этом случае равно null
, но вы можете установить его на все, что вам нужно.
Надеюсь, это полезно.
«Немного» хакерский способ сделать это:
<?php $foo = array(); var_dump('baz' == $tmp = &$foo['bar']); $foo['bar'] = 'baz'; var_dump('baz' == $tmp = &$foo['bar']);
http://codepad.viper-7.com/flXHCH
Очевидно, это не очень хороший способ сделать это. Но это удобно в других ситуациях. Например, я часто объявляю ярлыки для переменных GET и POST:
<?php $name =& $_GET['name']; // instead of $name = isset($_GET['name']) ? $_GET['name'] : null;
PS: Можно было бы назвать это «встроенным ==$_=&
специальным оператором сравнения»:
<?php var_dump('baz' ==$_=& $foo['bar']);
PPS: Ну, вы могли бы просто использовать
<?php var_dump('baz' == @$foo['bar']);
но это даже хуже, чем оператор ==$_=&
. Знаешь, людям не нравится оператор подавления ошибок.
Если вы перечисляете значения по умолчанию по ключу в массиве, это можно сделать следующим образом:
$foo = array('a' => 1, 'b' => 2); $defaults = array('b' => 55, 'c' => 44); $foo = array_merge($defaults, $foo); print_r($foo);
Результат:
Array ( [b] => 2 [c] => 44 [a] => 1 )
Чем больше пар ключ / значение, которое вы перечисляете по умолчанию, тем лучше становится код-гольф.