При зіставленні анонімної функції з анонімним масивом неможливо отримати доступ до ключів:
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);
Функція одного пострілу
Ми можемо використовувати сферу функцій, щоб запобігти обмеженню існуючих імен, але нам потрібно додати додатковий шар "use":
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) { });