Podczas mapowania anonimowej funkcji na anonimową tablicę nie ma możliwości uzyskania dostępu do kluczy:
array_map(
function($val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
array_reduce również nie ma dostępu do kluczy. array_walk może uzyskać dostęp do kluczy, ale tablica jest przekazywana przez odwołanie, co wymaga warstwy pośredniej.
Oto niektóre rozwiązania:
Tablica par
To źle, ponieważ zmieniamy oryginalną tablicę. Dodatkowo wywołania „array ()” na poziomie standardowym rosną liniowo wraz z długością tablicy:
array_map(
function($pair) use ($foo) {
list($key, $val) = $pair;
},
array(array(key1, val1),
array(key2, val2),
));
Zmienna tymczasowa
Działamy na oryginalnej tablicy, a schemat standardowy jest stały, ale możemy łatwo przebić istniejącą zmienną:
$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);
Funkcja jednorazowego użytku
Możemy użyć zakresu funkcji, aby zapobiec przebijaniu istniejących nazw, ale musimy dodać dodatkową warstwę „użytkowania”:
call_user_func(
function($arr) use ($foo) {
return array_map(function($key, $val) use ($foo) { },
array_keys($arr),
$arr);
},
array(key1 => val1,
key2 => val2,
));
Wieloargumentowa funkcja jednorazowa
Definiujemy funkcję, którą mapujemy w oryginalnym zakresie, aby zapobiec użyciu schematu „użyj”):
call_user_func(
function($f, $arr) {
return array_map($f, array_keys($arr), $arr);
},
function($key, $val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
Nowa funkcja
Warto zauważyć, że nasza ostatnia jednorazowa funkcja ma ładny, ogólny podpis i wygląda bardzo podobnie do tablicy array_map. Możemy chcieć nadać temu nazwę i użyć go ponownie:
function array_mapk($f, $arr) {
return array_map($f, array_keys($arr), $arr);
}
Nasz kod aplikacji staje się wtedy:
array_mapk(
function($key, $val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
Pośredni spacer po szyku
Pisząc powyższe, zignorowałem array_walk, ponieważ wymaga ona przekazania argumentu przez referencję; jednak od tego czasu zdałem sobie sprawę, że można łatwo obejść ten problem za pomocą call_user_func. Myślę, że to jak dotąd najlepsza wersja:
call_user_func(
'array_walk',
array(key1 => val1,
key2 => val2,
),
function($val, $key) use ($foo) { });