Hier ist meine sehr einfache, PHP 5.5-kompatible Lösung:
function array_map_assoc(callable $f, array $a) {
return array_column(array_map($f, array_keys($a), $a), 1, 0);
}
Der von Ihnen angegebene Callable sollte selbst ein Array mit zwei Werten zurückgeben, d return [key, value]
. H. Der innere Aufruf von array_map
erzeugt daher ein Array von Arrays. Dies wird dann von zurück in ein eindimensionales Array konvertiert array_column
.
Verwendung
$ordinals = [
'first' => '1st',
'second' => '2nd',
'third' => '3rd',
];
$func = function ($k, $v) {
return ['new ' . $k, 'new ' . $v];
};
var_dump(array_map_assoc($func, $ordinals));
Ausgabe
array(3) {
["new first"]=>
string(7) "new 1st"
["new second"]=>
string(7) "new 2nd"
["new third"]=>
string(7) "new 3rd"
}
Teilanwendung
Falls Sie die Funktion mehrmals mit verschiedenen Arrays, aber derselben Zuordnungsfunktion verwenden müssen, können Sie eine sogenannte Teilfunktionsanwendung (im Zusammenhang mit ' Currying ') ausführen , mit der Sie das Datenarray nur beim Aufruf übergeben können:
function array_map_assoc_partial(callable $f) {
return function (array $a) use ($f) {
return array_column(array_map($f, array_keys($a), $a), 1, 0);
};
}
...
$my_mapping = array_map_assoc_partial($func);
var_dump($my_mapping($ordinals));
Welches erzeugt die gleiche Ausgabe, gegeben $func
und $ordinals
sind wie früher.
HINWEIS: Wenn Ihre zugeordnete Funktion dieselbe Taste für zwei verschiedene Eingaben zurückgibt , gewinnt der mit der späteren Taste verknüpfte Wert . Kehren Sie das Eingabearray und das Ausgabeergebnis von array_map_assoc
um, damit frühere Schlüssel gewinnen können. (Die zurückgegebenen Schlüssel in meinem Beispiel können nicht kollidieren, da sie den Schlüssel des Quellarrays enthalten, der wiederum eindeutig sein muss.)
Alternative
Das Folgende ist eine Variante der oben genannten, die sich für einige als logischer erweisen könnte, aber PHP 5.6 erfordert:
function array_map_assoc(callable $f, array $a) {
return array_merge(...array_map($f, array_keys($a), $a));
}
In dieser Variante sollte Ihre bereitgestellte Funktion (über die das Datenarray zugeordnet ist) stattdessen ein assoziatives Array mit einer Zeile zurückgeben, d return [key => value]
. H. Das Ergebnis der Zuordnung des aufrufbaren Objekts wird dann einfach entpackt und an übergeben array_merge
. Wie zuvor führt die Rückgabe eines doppelten Schlüssels dazu, dass spätere Werte gewinnen.
nb Alex83690 hat in einem Kommentar festgestellt, dass die Verwendung array_replace
hier anstelle von array_merge
Ganzzahlschlüsseln erhalten würde. array_replace
Ändert das Eingabearray nicht, ist also für den Funktionscode sicher.
Wenn Sie mit PHP 5.3 bis 5.5 arbeiten, entspricht Folgendes. Es verwendet array_reduce
und den binären +
Array-Operator, um das resultierende zweidimensionale Array in ein eindimensionales Array zu konvertieren, wobei die Schlüssel erhalten bleiben:
function array_map_assoc(callable $f, array $a) {
return array_reduce(array_map($f, array_keys($a), $a), function (array $acc, array $a) {
return $acc + $a;
}, []);
}
Verwendung
Diese beiden Varianten würden also verwendet:
$ordinals = [
'first' => '1st',
'second' => '2nd',
'third' => '3rd',
];
$func = function ($k, $v) {
return ['new ' . $k => 'new ' . $v];
};
var_dump(array_map_assoc($func, $ordinals));
Beachten Sie die =>
statt ,
in $func
.
Die Ausgabe ist dieselbe wie zuvor und kann teilweise auf dieselbe Weise wie zuvor angewendet werden.
Zusammenfassung
Das Ziel der ursprünglichen Frage ist es, den Aufruf des Aufrufs so einfach wie möglich zu gestalten, auf Kosten einer komplizierteren Funktion, die aufgerufen wird. insbesondere, um das Datenarray als einzelnes Argument übergeben zu können, ohne die Schlüssel und Werte aufzuteilen. Verwenden Sie die zu Beginn dieser Antwort angegebene Funktion:
$test_array = ["first_key" => "first_value",
"second_key" => "second_value"];
$array_map_assoc = function (callable $f, array $a) {
return array_column(array_map($f, array_keys($a), $a), 1, 0);
};
$f = function ($key, $value) {
return [$key, $key . ' loves ' . $value];
};
var_dump(array_values($array_map_assoc($f, $test_array)));
Oder wir können nur für diese Frage eine array_map_assoc()
Funktionsvereinfachung vornehmen , bei der die Ausgabetasten gelöscht werden, da die Frage nicht nach ihnen fragt:
$test_array = ["first_key" => "first_value",
"second_key" => "second_value"];
$array_map_assoc = function (callable $f, array $a) {
return array_map($f, array_keys($a), $a);
};
$f = function ($key, $value) {
return $key . ' loves ' . $value;
};
var_dump($array_map_assoc($f, $test_array));
Die Antwort lautet also NEIN . Sie können es nicht vermeiden, anzurufen array_keys
, aber Sie können den Ort, an dem array_keys
der Aufruf erfolgt, in eine Funktion höherer Ordnung abstrahieren , was möglicherweise gut genug ist.