Есть ли лучший способ PHP для получения значения по умолчанию по ключу из массива (словарь)? - PullRequest
43 голосов
/ 14 июля 2011

В Python можно сделать:

foo = {}
assert foo.get('bar', 'baz') == 'baz'

В PHP можно перейти к тройному оператору, как в:

$foo = array();
assert( (isset($foo['bar'])) ? $foo['bar'] : 'baz' == 'baz');

Я ищу версию для гольфа. Могу ли я сделать это короче / лучше в PHP?

Ответы [ 8 ]

44 голосов
/ 08 августа 2014

Я только что придумал эту маленькую вспомогательную функцию:

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, а не ссылка. Надеюсь, это поможет!

44 голосов
/ 20 декабря 2016

Время проходит, и PHP развивается. PHP 7 теперь поддерживает оператор объединения нулей , ??:

// 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';
18 голосов
/ 23 июня 2014

Используйте оператор контроля ошибок @ с краткой версией PHP 5.3 для троичного оператора:

$bar = @$foo['bar'] ?: 'defaultvalue';
7 голосов
/ 13 марта 2014

Я считаю полезным создать такую ​​функцию:

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, ноВы можете установить все, что вам нужно.

Я надеюсь, что это полезно.

7 голосов
/ 14 июля 2011

PHP 5.3 имеет сокращенную версию троичного оператора:

$x = $foo ?: 'defaultvaluehere';

, что в основном равно

if (isset($foo)) {
   $x = $foo;
else {
   $x = 'defaultvaluehere';
}

В противном случае нет более короткого метода.

5 голосов
/ 14 июля 2011

"Немного" хакерский способ сделать это:

<?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']);

, но это даже хуже, чем оператор ==$_=&.Знаете, людям не очень нравится оператор подавления ошибок.

2 голосов
/ 23 сентября 2011

Если вы перечислите значения по умолчанию по ключу в массиве, это можно сделать следующим образом:

$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
)

Чем больше пар ключ / значение вы перечисляете по умолчанию, тем лучше становится код-гольф.

0 голосов
/ 14 марта 2019

Было решение, предложенное "Marc B" для использования троичного ярлыка $x = $foo ?: 'defaultvaluehere';, но оно все еще дает уведомления.Наверное это опечатка, может он имел ввиду ??или это было написано до выпуска PHP 7.Согласно Тернарное описание :

Начиная с PHP 5.3, можно опустить среднюю часть троичного оператора.Выражение expr1 ?: expr3 возвращает expr1, если expr1 равно TRUE, и expr3 в противном случае.

Но он не использует isset внутри и выдает уведомления.Чтобы избежать уведомлений, лучше использовать Null Coalescing Operator ??, который использует isset внутри него.Доступно в PHP 7.

Выражение (expr1) ??(expr2) оценивается как expr2, если expr1 равен NULL, и expr1 в противном случае.В частности, этот оператор не выдает уведомление , если левостороннее значение не существует, как и isset ().Это особенно полезно для ключей массива.

Пример # 5 Назначение значения по умолчанию

<?php
// Example usage for: Null Coalesce Operator
$action = $_POST['action'] ?? 'default';

// The above is identical to this if/else statement
if (isset($_POST['action'])) {
    $action = $_POST['action'];
} else {
    $action = 'default';
}

?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...