Gibt es eine Möglichkeit, so etwas zu tun:
$test_array = array("first_key" => "first_value",
"second_key" => "second_value");
var_dump(array_map(function($a, $b) { return "$a loves $b"; },
array_keys($test_array),
array_values($test_array)));
Aber anstatt die Variable aufzurufen array_keys
und array_values
direkt zu übergeben $test_array
?
Die gewünschte Ausgabe ist:
array(2) {
[0]=>
string(27) "first_key loves first_value"
[1]=>
string(29) "second_key loves second_value"
}
php
functional-programming
José Tomás Tocino
quelle
quelle
Antworten:
Nicht mit array_map, da es keine Schlüssel verarbeitet.
array_walk macht:
Es ändert jedoch das als Parameter angegebene Array, so dass es nicht genau funktionale Programmierung ist (da Sie die Frage so markiert haben). Wie im Kommentar erwähnt, werden dadurch nur die Werte des Arrays geändert, sodass die Schlüssel nicht den Angaben in der Frage entsprechen.
Sie könnten eine Funktion schreiben, die die Punkte über sich selbst korrigiert, wenn Sie möchten, wie folgt:
quelle
$a = "$b loves $a"
die gewünschte Ausgabe des OP erreichen.array_walk()
nicht das resultierende Array zurückgegeben wird, sondern ein Bool.Dies ist wahrscheinlich die kürzeste und am einfachsten zu begründende:
quelle
array_keys()
. Das scheint jedoch eine dumme Anforderung zu sein.Hier ist meine sehr einfache, PHP 5.5-kompatible Lösung:
Der von Ihnen angegebene Callable sollte selbst ein Array mit zwei Werten zurückgeben, d
return [key, value]
. H. Der innere Aufruf vonarray_map
erzeugt daher ein Array von Arrays. Dies wird dann von zurück in ein eindimensionales Array konvertiertarray_column
.Verwendung
Ausgabe
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:
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:
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 übergebenarray_merge
. Wie zuvor führt die Rückgabe eines doppelten Schlüssels dazu, dass spätere Werte gewinnen.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:Verwendung
Diese beiden Varianten würden also verwendet:
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:
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:Die Antwort lautet also NEIN . Sie können es nicht vermeiden, anzurufen
array_keys
, aber Sie können den Ort, an demarray_keys
der Aufruf erfolgt, in eine Funktion höherer Ordnung abstrahieren , was möglicherweise gut genug ist.quelle
array_merge
durcharray_replace
Tasten zu erhalten , die ganzen Zahlen sein würde.Mit PHP5.3 oder höher:
quelle
So habe ich das in meinem Projekt umgesetzt.
quelle
Schau hier! Es gibt eine triviale Lösung!
Wie in der Frage angegeben, hat
array_map
bereits genau die Funktionalität erforderlich . Die anderen Antworten hier überkomplizieren die Dinge ernsthaft:array_walk
sind nicht funktionsfähig.Verwendung
Genau so, wie Sie es von Ihrem Beispiel erwarten würden:
quelle
qrrqy_keys()
zu kompliziert, da die angegebene Frage nicht für #reasons verwendet werden sollteMit "manuelle Schleife" meinte ich das Schreiben einer benutzerdefinierten Funktion, die verwendet
foreach
. Dies gibt ein neues Array zurück, wiearray_map
dies der Fall ist, da der Funktionsumfang$array
eine Kopie und keine Referenz verursacht:Ihre Technik
array_map
mitarray_keys
obwohl scheint tatsächlich einfacher und leistungsfähiger zu sein, da Sie sienull
als Rückruf verwenden können, um die Schlüssel-Wert-Paare zurückzugeben:quelle
unset( $value )
weil es noch im definierten Bereich existiert.Basierend auf der Antwort von eis habe ich Folgendes getan, um zu vermeiden, dass das ursprüngliche Array durcheinander gebracht wird:
quelle
array_walk
da Sie es im Abschluss nicht referenzieren.Ich habe diese Funktion basierend auf der Antwort von eis erstellt :
Beispiel:
Ausgabe:
Natürlich können Sie damit
array_values
genau das zurückgeben, was OP will.quelle
$arr
vom Typ Array ist, aber wenn Sie Ihre Argumente typ andeuten , wiecallable
undarray
Sie können stattdessen den Scheck fallenis_callable
. Als Nächstes weisen Sie $ value eine Zuweisung zu, die dann nicht verwendet wird. Sie sollten den Rückgabewert einfach ignorieren. Drittens wäre es besser, eine Ausnahme in den Rückruf zu werfen, als false zurückzugeben. Sie würden dann entweder immer einen gültigen Wert zurückgeben oder immer werfen.Die YaLinqo- Bibliothek * ist für diese Art von Aufgabe gut geeignet. Es ist ein Port von LINQ aus .NET, der Werte und Schlüssel in allen Rückrufen vollständig unterstützt und SQL ähnelt. Beispielsweise:
oder nur:
Hier
'"$k loves $v"'
ist eine Verknüpfung für die vollständige Schließungssyntax, die diese Bibliothek unterstützt.toArray()
am Ende ist optional. Die Methodenkette gibt einen Iterator zurück. Wenn das Ergebnis nur mit iteriert werden mussforeach
,toArray
kann der Aufruf entfernt werden.* von mir entwickelt
quelle
Ich würde so etwas machen:
Ergebnisse:
quelle
Ich werde noch eine weitere Lösung für das Problem mit Version 5.6 oder höher hinzufügen. Ich weiß nicht, ob es effizienter ist als die bereits großartigen Lösungen (wahrscheinlich nicht), aber für mich ist es einfach einfacher zu lesen:
Unter Verwendung
strval()
als Beispiel Funktion in demarray_map
, werden diese erzeugen:Hoffentlich bin ich nicht der einzige, der das ziemlich einfach zu verstehen findet.
array_combine
Erstellt einkey => value
Array aus einem Array von Schlüsseln und einem Array von Werten, der Rest ist ziemlich selbsterklärend.quelle
Sie können die Kartenmethode aus dieser Array-Bibliothek verwenden , um genau das zu erreichen, was Sie möchten:
Außerdem werden Schlüssel beibehalten und neue Arrays zurückgegeben, ganz zu schweigen von einigen verschiedenen Modi, die Ihren Anforderungen entsprechen.
quelle
Quelle
quelle
Ich mag immer die Javascript-Variante der Array-Map. Die einfachste Version davon wäre:
Jetzt können Sie ihm einfach eine Rückruffunktion zum Erstellen der Werte übergeben.
quelle
h(g(f($data)))
giltf
, danng
, dannh
auf Ihre Daten. In der funktionalen Programmierung wird es allgemein als vielseitiger angesehen, eine Funktion zu haben, die dieselbe Operation für Taucherdaten ausführt, als eine Funktion, die Taucherfunktionen auf einen festen Datensatz anwendet.Eine andere Möglichkeit, dies mit (out) Schlüssel zu tun:
quelle
Ich sehe, es fehlt die offensichtliche Antwort:
Funktioniert genau wie array_map. Fast.
Eigentlich ist es nicht rein,
map
wie Sie es aus anderen Sprachen kennen. PHP ist sehr seltsam, daher erfordert es einige sehr seltsame Benutzerfunktionen, denn wir wollen unsere genau gebrochenen nicht auflösenworse is better
Ansatz .Wirklich, es ist überhaupt nicht
map
. Trotzdem ist es sehr nützlich.Der erste offensichtliche Unterschied zu array_map besteht darin, dass der Rückruf Ausgaben
each()
von jedem Eingabearray anstelle von Werten allein übernimmt . Sie können immer noch mehrere Arrays gleichzeitig durchlaufen.Der zweite Unterschied ist die Art und Weise, wie der Schlüssel behandelt wird, nachdem er vom Rückruf zurückgegeben wurde. Der Rückgabewert der Rückruffunktion sollte sein
array('new_key', 'new_value')
. Schlüssel können und werden geändert, dieselben Schlüssel können sogar dazu führen, dass der vorherige Wert überschrieben wird, wenn derselbe Schlüssel zurückgegeben wurde. Dies ist kein allgemeinesmap
Verhalten, ermöglicht jedoch das Umschreiben von Schlüsseln.Die dritte seltsame Sache ist, wenn Sie den
key
Rückgabewert weglassen (entweder vonarray(1 => 'value')
oderarray(null, 'value')
), wird ein neuer Schlüssel zugewiesen, als ob er$array[] = $value
verwendet worden wäre. Das ist auch nichtmap
das übliche Verhalten, aber es ist manchmal praktisch, denke ich.Die vierte seltsame Sache ist, wenn die Rückruffunktion keinen Wert zurückgibt oder zurückgibt
null
, wird der gesamte Satz aktueller Schlüssel und Werte in der Ausgabe weggelassen und einfach übersprungen. Diese Funktion ist völligmap
einzigartig, aber sie würde diese Funktion zu einem hervorragenden Stunt-Double machenarray_filter_assoc
, wenn es eine solche Funktion gäbe.Wenn Sie das zweite Element (
1 => ...
) (den Wertteil ) in der Rückrufrückgabe weglassen ,null
wird anstelle des realen Werts verwendet.Alle anderen Elemente außer denen mit Schlüsseln
0
und1
in der Rückrufrückgabe werden ignoriert.Und schließlich, wenn Lambda einen Wert außer
null
oder Array zurückgibt , wird es so behandelt, als ob sowohl Schlüssel als auch Wert weggelassen würden, also:null
wird als Wert verwendetHINWEIS:
Im Gegensatz zu in
array_map
werden alle Nicht-Array-Parameterarray_map_assoc
mit Ausnahme des ersten Rückrufparameters stillschweigend in Arrays umgewandelt.BEISPIELE:
// TODO: examples, anyone?
quelle