Was genau ist das der Unterschied zwischen array_map
, array_walk
und array_filter
. Aus der Dokumentation geht hervor, dass Sie eine Rückruffunktion übergeben können, um eine Aktion für das bereitgestellte Array auszuführen. Aber ich scheine keinen besonderen Unterschied zwischen ihnen zu finden.
Führen sie das Gleiche aus?
Können sie austauschbar verwendet werden?
Ich würde mich über Ihre Hilfe bei einem anschaulichen Beispiel freuen, wenn sie überhaupt unterschiedlich sind.
Antworten:
array_map
kann die Werte in Eingabearrays nicht ändern, solange dies möglicharray_walk
ist; insbesonderearray_map
ändert nie seine Argumente.array_map
kann nicht mit den Array-Schlüsseln arbeiten,array_walk
kann.array_map
Gibt ein neues Array zurück, gibtarray_walk
nur zurücktrue
. Wenn Sie also kein Array als Ergebnis des Durchlaufens eines Arrays erstellen möchten, sollten Sie verwendenarray_walk
.array_map
kann auch eine beliebige Anzahl von Arrays empfangen und diese parallel durchlaufen, währendarray_walk
nur eines bearbeitet wird .array_walk
kann einen zusätzlichen beliebigen Parameter empfangen, der an den Rückruf übergeben wird. Dies ist seit PHP 5.3 (als anonyme Funktionen eingeführt wurden) größtenteils irrelevant .array_map
hat die gleiche Länge wie das größte Eingabearray.array_walk
gibt kein Array zurück, kann aber gleichzeitig die Anzahl der Elemente des ursprünglichen Arrays nicht ändern;array_filter
wählt nur eine Teilmenge der Elemente des Arrays gemäß einer Filterfunktion aus. Die Schlüssel bleiben erhalten.Beispiel:
Ergebnis:
quelle
array_map(callback($key, $value), array_keys($array), $array)
Die Idee der Zuordnung einer Funktion zu Array von Daten stammen aus funktionalen Programmierung. Sie sollten nicht darüber nachdenken ,
array_map
wie eineforeach
Schleife , die eine Funktion auf jedes Element des Arrays nennt (auch wenn das ist , wie es implementiert). Es sollte so gedacht werden, dass die Funktion unabhängig auf jedes Element im Array angewendet wird.Theoretisch können Dinge wie die Funktionszuordnung parallel durchgeführt werden, da die auf die Daten angewendete Funktion NUR die Daten und NICHT den globalen Zustand beeinflussen sollte. Dies liegt daran, dass Sie eine
array_map
beliebige Reihenfolge auswählen können, in der die Funktion auf die Elemente in angewendet werden soll (obwohl dies in PHP nicht der Fall ist).array_walk
Auf der anderen Seite ist es der genau entgegengesetzte Ansatz zum Umgang mit Datenfeldern. Anstatt jedes Element separat zu behandeln, wird ein Status (&$userdata
) verwendet und das Element kann an Ort und Stelle bearbeitet werden (ähnlich wie bei einer foreach-Schleife). Da jedes Mal, wenn ein Element auf das Element$funcname
angewendet wird, kann es den globalen Status des Programms ändern und erfordert daher eine einzige korrekte Art der Verarbeitung der Elemente.Zurück im PHP-Land
array_map
undarray_walk
fast identisch, außer dassarray_walk
Sie mehr Kontrolle über die Iteration von Daten haben und normalerweise verwendet werden, um die Daten an Ort und Stelle zu "ändern", anstatt ein neues "geändertes" Array zurückzugeben.array_filter
ist wirklich eine Anwendung vonarray_walk
(oderarray_reduce
) und es ist mehr oder weniger nur der Einfachheit halber vorgesehen.quelle
array_filter()
mit implementiert werden kannarray_walk()
?Aus der Dokumentation,
array_walk nimmt ein Array und eine Funktion
F
und ändert sie, indem jedes Element x durch ersetzt wirdF(x)
.array_map macht genau das Gleiche, außer dass anstelle einer Änderung an Ort und Stelle ein neues Array mit den transformierten Elementen zurückgegeben wird.
array_filter with function entfernt
F
anstelle der Transformation der Elemente alle Elemente, für die diesF(x)
nicht der Fall istquelle
array_walk
ein Array wie zurückgegeben wurde,array_map
und stellte fest, dass das Problem in meiner Funktion lag. Erst als ich das sah, wurde mir klar, dass der Rückgabetyp boolesch ist.Die anderen Antworten zeigen den Unterschied zwischen array_walk (direkte Änderung) und array_map (modifizierte Kopie zurückgeben) recht gut. Array_reduce wird jedoch nicht wirklich erwähnt. Dies ist eine aufschlussreiche Methode, um array_map und array_filter zu verstehen.
Die Funktion array_reduce verwendet ein Array, eine Funktion mit zwei Argumenten und einen 'Akkumulator' wie folgt:
Die Elemente des Arrays werden unter Verwendung der angegebenen Funktion einzeln mit dem Akkumulator kombiniert. Das Ergebnis des obigen Aufrufs ist dasselbe wie folgt:
Wenn Sie lieber in Schleifen denken möchten, gehen Sie wie folgt vor (ich habe dies tatsächlich als Fallback verwendet, als array_reduce nicht verfügbar war):
Diese Schleifenversion macht deutlich, warum ich das dritte Argument als "Akkumulator" bezeichnet habe: Wir können es verwenden, um Ergebnisse durch jede Iteration zu akkumulieren.
Was hat das mit array_map und array_filter zu tun? Es stellt sich heraus, dass beide eine bestimmte Art von array_reduce sind. Wir können sie folgendermaßen umsetzen:
Ignorieren Sie die Tatsache, dass array_map und array_filter ihre Argumente in einer anderen Reihenfolge verwenden. Das ist nur eine weitere Besonderheit von PHP. Der wichtige Punkt ist, dass die rechte Seite bis auf die Funktionen, die ich $ MAP und $ FILTER genannt habe, identisch ist. Wie sehen sie also aus?
Wie Sie sehen können, nehmen beide Funktionen den $ -Akkumulator auf und geben ihn erneut zurück. Bei diesen Funktionen gibt es zwei Unterschiede:
Beachten Sie, dass dies alles andere als nutzlose Kleinigkeiten sind. Wir können es verwenden, um unsere Algorithmen effizienter zu machen!
Wir können oft Code wie diese beiden Beispiele sehen:
Wenn Sie array_map und array_filter anstelle von Schleifen verwenden, sehen diese Beispiele sehr gut aus. Es kann jedoch sehr ineffizient sein, wenn $ input groß ist, da der erste Aufruf (Map oder Filter) $ input durchläuft und ein Zwischenarray erstellt. Dieses Zwischenarray wird direkt an den zweiten Aufruf übergeben, der das Ganze erneut durchläuft. Dann muss das Zwischenarray mit Müll gesammelt werden.
Wir können dieses Zwischenarray loswerden, indem wir die Tatsache ausnutzen, dass array_map und array_filter beide Beispiele für array_reduce sind. Wenn wir sie kombinieren, müssen wir $ input in jedem Beispiel nur einmal durchlaufen:
HINWEIS: Meine Implementierungen von array_map und array_filter oben verhalten sich nicht genau wie die von PHP, da meine array_map jeweils nur ein Array verarbeiten kann und mein array_filter nicht "leer" als Standardfunktion für $ verwendet. Außerdem werden keine Schlüssel beibehalten.
Es ist nicht schwer, sie dazu zu bringen, sich wie PHPs zu verhalten, aber ich hatte das Gefühl, dass diese Komplikationen es schwieriger machen würden, die Kernidee zu erkennen.
quelle
Mit der folgenden Überarbeitung sollen die Array_filer (), array_map () und array_walk () von PHP klarer abgegrenzt werden, die alle aus der funktionalen Programmierung stammen:
array_filter () filtert Daten heraus und erzeugt als Ergebnis ein neues Array, das nur die gewünschten Elemente des vorherigen Arrays enthält, wie folgt:
Live-Code hier
Alle numerischen Werte werden aus $ array herausgefiltert, wobei $ nur mit Obstsorten gefiltert wird.
array_map () erstellt auch ein neues Array, aber im Gegensatz zu array_filter () enthält das resultierende Array jedes Element der Eingabe $ gefiltert, jedoch mit geänderten Werten, da auf jedes Element ein Rückruf angewendet wird :
Live-Code hier
Der Code wendet in diesem Fall einen Rückruf mit dem integrierten strtoupper () an, aber eine benutzerdefinierte Funktion ist auch eine weitere praktikable Option. Der Rückruf gilt für jedes Element von $ gefiltert und erzeugt dadurch $ nu, dessen Elemente Großbuchstaben enthalten.
Im nächsten Snippet durchläuft Array walk () $ nu und nimmt Änderungen an jedem Element gegenüber dem Referenzoperator '&' vor. Die Änderungen erfolgen, ohne ein zusätzliches Array zu erstellen. Der Wert jedes Elements ändert sich an Ort und Stelle in eine informativere Zeichenfolge, die seinen Schlüssel, seine Kategorie und seinen Wert angibt.
Siehe Demo
Hinweis: Die Rückruffunktion in Bezug auf array_walk () verwendet zwei Parameter, die automatisch den Wert und den Schlüssel eines Elements und auch in dieser Reihenfolge erfassen, wenn sie von array_walk () aufgerufen werden. (Mehr hier ).
quelle
$lambda
und$callback
nur Eta-Erweiterungen vorhandener Funktionen sind und daher vollständig redundant sind. Sie können das gleiche Ergebnis$filtered = array_filter($array, 'ctype_alpha');
$nu = array_map('strtoupper', $filtered);