При отображении анонимной функции на анонимный массив нет возможности получить доступ к ключам:
array_map(
function($val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
array_reduce также не получает доступа к ключам. array_walk может обращаться к ключам, но массив передается по ссылке, что требует уровня косвенного обращения.
Вот некоторые решения:
Массив пар
Это плохо, поскольку мы меняем исходный массив. Кроме того, стандартные вызовы array () линейно увеличиваются с увеличением длины массива:
array_map(
function($pair) use ($foo) {
list($key, $val) = $pair;
},
array(array(key1, val1),
array(key2, val2),
));
Временная переменная
Мы работаем с исходным массивом, и шаблон постоянен, но мы можем легко затереть существующую переменную:
$i_hope_this_does_not_conflict = array(key1 => val1,
key2 => val2,
);
array_map(
function($key, $val) use ($foo) { },
array_keys($i_hope_this_does_not_conflict),
$i_hope_this_does_not_conflict);
unset($i_hope_this_does_not_conflict);
Одноразовая функция
Мы можем использовать область видимости функции, чтобы предотвратить затирание существующих имен, но должны добавить дополнительный уровень «использования»:
call_user_func(
function($arr) use ($foo) {
return array_map(function($key, $val) use ($foo) { },
array_keys($arr),
$arr);
},
array(key1 => val1,
key2 => val2,
));
Одноразовая функция с несколькими аргументами
Мы определяем функцию, которую мы отображаем в исходной области видимости, чтобы предотвратить "использование" шаблона):
call_user_func(
function($f, $arr) {
return array_map($f, array_keys($arr), $arr);
},
function($key, $val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
Новая функция
Интересно отметить, что наша последняя одноразовая функция имеет хорошую общую сигнатуру и очень похожа на array_map. Мы могли бы захотеть дать этому имя и использовать его повторно:
function array_mapk($f, $arr) {
return array_map($f, array_keys($arr), $arr);
}
Код нашего приложения становится таким:
array_mapk(
function($key, $val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
Непрямая прогулка по массиву
При написании вышесказанного я проигнорировал array_walk, поскольку он требует, чтобы его аргумент передавался по ссылке; однако с тех пор я понял, что это легко обойти, используя call_user_func. Я думаю, что это лучшая версия на данный момент:
call_user_func(
'array_walk',
array(key1 => val1,
key2 => val2,
),
function($val, $key) use ($foo) { });