Ich benutze eine Karte in PHP wie folgt:
function func($v) {
return $v * 2;
}
$values = array(4, 6, 3);
$mapped = array_map(func, $values);
var_dump($mapped);
Ist es möglich, den Index des Wertes in der Funktion zu erhalten?
Außerdem - wenn ich Code schreibe, der den Index benötigt, sollte ich eine for-Schleife anstelle einer Karte verwenden?
array_map()
mit einer beliebigen Anzahl von Argumenten liefern :)array_keys
in derselben Reihenfolge wie im ursprünglichen Array bleiben. Daher könnten Sie Schlüssel falschen Werten zuordnen. Der sichere Ansatz besteht darin, nurarray_keys
das zweite Argument von zu verwendenarray_map
und das Array dann mit deruse
Anweisung an den Abschluss zu übergeben .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) { /* ... */ });
quelle
Sehr einfach:
Nur array_map Funktion: hat keinen Indexschlüssel!
$params = [4,6,2,11,20]; $data = array_map(function($v) { return ":id{$v}";}, $params); array (size=5) 0 => string ':id4' (length=4) 1 => string ':id6' (length=4) 2 => string ':id2' (length=4) 3 => string ':id11' (length=5) 4 => string ':id20' (length=5)
Kombinieren Sie jetzt mit array_keys:
$data = array_map( function($k) use ($params) { return ":id{$k}_${params[$k]}"; }, array_keys($params) ); array (size=5) 0 => string ':id0_4' (length=6) 1 => string ':id1_6' (length=6) 2 => string ':id2_2' (length=6) 3 => string ':id3_11' (length=7) 4 => string ':id4_20' (length=7)
quelle