Wenn Sie eine anonyme Funktion einem anonymen Array zuordnen, können Sie nicht auf die Schlüssel zugreifen:
array_map(
function($val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
array_reduce erhält auch keinen Zugriff auf die Schlüssel. array_walk kann auf Schlüssel zugreifen, das Array wird jedoch als Referenz übergeben, was eine Indirektionsebene erfordert.
Einige Lösungen sind:
Array von Paaren
Das ist schlecht, da wir das ursprüngliche Array ändern. Außerdem nehmen die Boilerplate-Aufrufe "array ()" linear mit der Länge des Arrays zu:
array_map(
function($pair) use ($foo) {
list($key, $val) = $pair;
},
array(array(key1, val1),
array(key2, val2),
));
Temporäre Variable
Wir arbeiten mit dem ursprünglichen Array, und die Boilerplate ist konstant, aber wir können eine vorhandene Variable leicht blockieren:
$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);
One-Shot-Funktion
Wir können den Funktionsumfang verwenden, um das Überfallen vorhandener Namen zu verhindern, müssen jedoch eine zusätzliche Ebene für "Verwendung" hinzufügen:
call_user_func(
function($arr) use ($foo) {
return array_map(function($key, $val) use ($foo) { },
array_keys($arr),
$arr);
},
array(key1 => val1,
key2 => val2,
));
One-Shot-Funktion mit mehreren Argumenten
Wir definieren die Funktion, die wir zuordnen, im ursprünglichen Bereich, um zu verhindern, dass das Boilerplate "verwendet" wird:
call_user_func(
function($f, $arr) {
return array_map($f, array_keys($arr), $arr);
},
function($key, $val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
Neue Funktion
Das Interessante ist, dass unsere letzte One-Shot-Funktion eine schöne, generische Signatur hat und Array_Map sehr ähnlich sieht. Vielleicht möchten wir diesem einen Namen geben und ihn wiederverwenden:
function array_mapk($f, $arr) {
return array_map($f, array_keys($arr), $arr);
}
Unser Anwendungscode lautet dann:
array_mapk(
function($key, $val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
Indirekter Array-Spaziergang
Beim Schreiben des obigen Artikels habe ich array_walk ignoriert, da das Argument als Referenz übergeben werden muss. Inzwischen habe ich jedoch festgestellt, dass es einfach ist, dies mit call_user_func zu umgehen. Ich denke, dies ist die bisher beste Version:
call_user_func(
'array_walk',
array(key1 => val1,
key2 => val2,
),
function($val, $key) use ($foo) { });