Ok, dies ist eher eine Informatikfrage als eine Frage, die auf einer bestimmten Sprache basiert. Gibt es jedoch einen Unterschied zwischen einer Kartenoperation und einer Foreach-Operation? Oder sind es einfach unterschiedliche Namen für dasselbe?
foreach
language-agnostic
computer-science
map-function
Robert Gould
quelle
quelle
Iterator[String]
von bekommescala.io.Source.fromFile("/home/me/file").getLines()
und mich darauf.foreach(s => ptintln(s))
bewerbe, aber es wird gleich danach leer. Zur gleichen Zeit, wenn ich mich darauf bewerbe.map(ptintln(_))
- es wird einfach leer und nichts wird gedruckt.Antworten:
Anders.
foreach iteriert über eine Liste und wendet auf jedes Listenmitglied eine Operation mit Nebenwirkungen an (z. B. Speichern jeder in der Datenbank).
map iteriert über eine Liste, transformiert jedes Mitglied dieser Liste und gibt eine andere Liste derselben Größe mit den transformierten Mitgliedern zurück (z. B. Konvertieren einer Liste von Zeichenfolgen in Großbuchstaben).
quelle
map
ist nicht in der Ausführung ihrer zugrundeliegenden Logik zur Folge haben, bis , wenn die erwartete transformierte Liste beschworen wird. Im Gegensatz dazu wirdforeach
die Operation sofort berechnet.Der wichtige Unterschied zwischen ihnen besteht darin, dass
map
alle Ergebnisse in einer Sammlung zusammengefasst werden, währendforeach
nichts zurückgegeben wird.map
wird normalerweise verwendet, wenn Sie eine Sammlung von Elementen mit einer Funktion transformieren möchten, währendforeach
einfach eine Aktion für jedes Element ausgeführt wird.quelle
Kurz gesagt,
foreach
dient zum Anwenden einer Operation auf jedes Element einer Sammlung von Elementen, währendmap
zum Transformieren einer Sammlung in eine andere.Es gibt zwei signifikante Unterschiede zwischen
foreach
undmap
.foreach
hat keine konzeptionellen Einschränkungen für die Operation, die angewendet wird, außer vielleicht ein Element als Argument zu akzeptieren. Das heißt, die Operation kann nichts tun, kann eine Nebenwirkung haben, kann einen Wert zurückgeben oder kann keinen Wert zurückgeben. Allesforeach
tun müssen, ist, eine Sammlung von Elementen zu durchlaufen und die Operation auf jedes Element anzuwenden.map
Auf der anderen Seite gibt es eine Einschränkung für die Operation: Sie erwartet, dass die Operation ein Element zurückgibt und wahrscheinlich auch ein Element als Argument akzeptiert. Diemap
Operation durchläuft eine Sammlung von Elementen, wendet die Operation auf jedes Element an und speichert schließlich das Ergebnis jedes Aufrufs der Operation in einer anderen Sammlung. Mit anderen Worten, dasmap
transformiert eine Sammlung in eine andere.foreach
arbeitet mit einer einzigen Sammlung von Elementen. Dies ist die Eingabesammlung.map
arbeitet mit zwei Sammlungen von Elementen: der Eingabesammlung und der Ausgabesammlung.Es ist kein Fehler, die beiden Algorithmen in Beziehung zu setzen: Tatsächlich können Sie die beiden Algorithmen hierarchisch anzeigen, wobei
map
eine Spezialisierung von vorliegtforeach
. Das heißt, Sie könnenforeach
das Argument der Operation verwenden und transformieren und in eine andere Sammlung einfügen. Derforeach
Algorithmus ist also eine Abstraktion, eine Verallgemeinerung desmap
Algorithmus. Daforeach
der Betrieb nicht eingeschränkt ist, können wir mit Sicherheit sagen, dass diesforeach
der einfachste Schleifenmechanismus auf dem Markt ist und alles kann, was eine Schleife tun kann.map
Wie auch andere, speziellere Algorithmen dienen der Ausdruckskraft: Wenn Sie eine Sammlung in eine andere abbilden (oder transformieren) möchten, ist Ihre Absicht bei Verwendung klarermap
als bei Verwendungforeach
.Wir können diese Diskussion weiter ausdehnen und den
copy
Algorithmus betrachten: eine Schleife, die eine Sammlung klont. Auch dieser Algorithmus ist eine Spezialisierung desforeach
Algorithmus. Sie können eine Operation definieren, die bei einem bestimmten Element dasselbe Element in eine andere Sammlung einfügt. Wenn Sieforeach
diese Operation verwenden, haben Sie dencopy
Algorithmus tatsächlich ausgeführt, allerdings mit reduzierter Klarheit, Ausdruckskraft oder Aussagekraft. Gehen wir noch weiter: Wir können sagen, dass diesmap
eine Spezialisierung voncopy
, selbst eine Spezialisierung von istforeach
.map
kann jedes der Elemente ändern, über die es iteriert. Wennmap
keines der Elemente geändert wird, werden lediglich die Elemente kopiert und verwendet Kopie verwendet würde die Absicht klarer ausdrücken.Der
foreach
Algorithmus selbst kann abhängig von der Sprache einen Rückgabewert haben oder nicht. Gibt in C ++ beispielsweiseforeach
die ursprünglich empfangene Operation zurück. Die Idee ist, dass die Operation möglicherweise einen Status hat, und Sie möchten möglicherweise, dass diese Operation überprüft, wie sie sich über die Elemente entwickelt hat.map
kann auch einen Wert zurückgeben oder nicht. In C ++transform
(das Äquivalent fürmap
hier) wird zufällig ein Iterator an das Ende des Ausgabecontainers (Sammlung) zurückgegeben. In Ruby ist der Rückgabewert vonmap
die Ausgabesequenz (Sammlung). Der Rückgabewert der Algorithmen ist also wirklich ein Implementierungsdetail. Ihre Wirkung kann oder kann nicht das sein, was sie zurückgeben.quelle
.forEach()
die Implementierung.map()
finden Sie hier: stackoverflow.com/a/39159854/1524693Array.protototype.map
Methode &Array.protototype.forEach
sind beide ziemlich ähnlich.Führen Sie den folgenden Code aus: http://labs.codecademy.com/bw1/6#:workspace
Sie geben genau das gleiche Ergebnis.
Aber die Wendung kommt, wenn Sie den folgenden Code ausführen: -
Hier habe ich einfach das Ergebnis des Rückgabewerts aus den Methoden map und forEach zugewiesen.
Jetzt ist das Ergebnis etwas knifflig!
Fazit
Array.prototype.map
gibt ein Array zurück,Array.prototype.forEach
tut es aber nicht. Sie können also das zurückgegebene Array innerhalb der an die Map-Methode übergebenen Rückruffunktion bearbeiten und dann zurückgeben.Array.prototype.forEach
Geht nur durch das angegebene Array, damit Sie Ihre Arbeit erledigen können, während Sie durch das Array gehen.quelle
Der sichtbarste Unterschied besteht darin, dass die Karte das Ergebnis in einer neuen Sammlung sammelt, während foreach nur für die Ausführung selbst durchgeführt wird.
Es gibt jedoch einige zusätzliche Annahmen: Da der 'Zweck' der Karte die neue Liste von Werten ist, spielt die Reihenfolge der Ausführung keine Rolle. In der Tat generieren einige Ausführungsumgebungen parallelen Code oder führen sogar Memoizing ein, um das Aufrufen wiederholter Werte oder Faulheit zu vermeiden, um das Aufrufen von Werten überhaupt zu vermeiden.
foreach hingegen wird speziell für die Nebenwirkungen genannt; Daher ist die Reihenfolge wichtig und kann normalerweise nicht parallelisiert werden.
quelle
Kurze Antwort:
map
undforEach
sind anders. Auch informell gesehenmap
ist eine strikte Obermenge vonforEach
.Lange Antwort: Lassen Sie uns zunächst eine einzeilige Beschreibung von
forEach
und erstellenmap
:forEach
iteriert über alle Elemente und ruft die jeweils bereitgestellte Funktion auf.map
iteriert über alle Elemente, ruft die angegebene Funktion für jedes Element auf und erzeugt ein transformiertes Array, indem das Ergebnis jedes Funktionsaufrufs gespeichert wird.In vielen Sprachen
forEach
wird oft nur genannteach
. In der folgenden Diskussion wird JavaScript nur als Referenz verwendet. Es könnte wirklich jede andere Sprache sein.Lassen Sie uns nun jede dieser Funktionen verwenden.
Verwenden von
forEach
:Aufgabe 1: Schreiben Sie eine Funktion
printSquares
, die ein Array von Zahlen akzeptiertarr
und das Quadrat jedes Elements darin druckt.Lösung 1:
Verwenden von
map
:Aufgabe 2: Schreiben Sie eine Funktion
selfDot
, die ein Array von Zahlen akzeptiert und ein Arrayarr
zurückgibt, in dem jedes Element das Quadrat des entsprechenden Elements in istarr
.Nebenbei: Hier versuchen wir in Slang-Begriffen, das Eingabearray zu quadrieren. Formal ausgedrückt versuchen wir, das Punktprodukt mit sich selbst zu berechnen.
Lösung 2:
Wie ist
map
eine Obermenge vonforEach
?Sie können
map
beide Aufgaben, Aufgabe 1 und Aufgabe 2 , lösen . Sie könnenforEach
die Aufgabe 2 jedoch nicht verwenden .In Lösung 1 , wenn Sie einfach ersetzen
forEach
durchmap
, wird die Lösung noch gültig sein. In Lösung 2 wird Ihre zuvor funktionierende Lösung jedoch durch Ersetzenmap
durchforEach
beschädigt.Implementierung
forEach
in Bezug aufmap
:Eine andere Möglichkeit,
map
die Überlegenheit zu erkennen , ist die UmsetzungforEach
in Bezug aufmap
. Da wir gute Programmierer sind, werden wir uns nicht der Verschmutzung von Namespaces hingeben. Wir werden unsereforEach
einfach anrufeneach
.Wenn Sie den
prototype
Unsinn nicht mögen , können Sie loslegen:Also, ähm ... warum?
forEach
überhaupt?Die Antwort lautet Effizienz. Wenn Sie nicht daran interessiert sind, ein Array in ein anderes Array umzuwandeln, warum sollten Sie das transformierte Array berechnen? Nur um es wegzuwerfen? Natürlich nicht! Wenn Sie keine Transformation wünschen, sollten Sie keine Transformation durchführen.
Während Map zur Lösung von Aufgabe 1 verwendet werden kann , sollte dies wahrscheinlich nicht der Fall sein. Für jeden ist der richtige Kandidat dafür.
Ursprüngliche Antwort:
Obwohl ich der Antwort von @madlep weitgehend zustimme, möchte ich darauf hinweisen, dass dies
map()
eine strikte Supermenge von istforEach()
.Ja,
map()
wird normalerweise verwendet, um ein neues Array zu erstellen. Es kann jedoch auch verwendet werden, um das aktuelle Array zu ändern.Hier ist ein Beispiel:
Im obigen Beispiel
a
wurde zweckmäßigerweise so eingestellt, dassa[i] === i
zi < a.length
. Trotzdem zeigt es die Kraft vonmap()
.Hier ist die offizielle Beschreibung von
map()
. Beachten Sie, dass diesmap()
sogar das Array ändern kann, auf dem es aufgerufen wird! Hagelmap()
.Hoffe das hat geholfen.
Bearbeitet am 10.11.2015: Ausarbeitung hinzugefügt.
quelle
map
Funktion hätte, aber neinforEach
; Könntest du nicht einfach nicht verwendenmap
anstattforEach
? Auf der anderen Seite, wenn eine SpracheforEach
aber nein hättemap
, müssten Sie Ihre eigene implementierenmap
. Sie könnten nicht einfachforEach
anstelle von verwendenmap
. Sag mir was du denkst.Hier ist ein Beispiel in Scala mit Listen: Map gibt Liste zurück, foreach gibt nichts zurück.
Map gibt also die Liste zurück, die sich aus der Anwendung der Funktion f auf jedes Listenelement ergibt:
Foreach wendet nur f auf jedes Element an:
quelle
Wenn Sie insbesondere über Javascript sprechen, besteht der Unterschied darin, dass
map
es sich dabei um eine Schleifenfunktion handeltforEach
es sich um einen Iterator handelt.Verwenden
map
Sie diese Option, wenn Sie auf jedes Mitglied der Liste eine Operation anwenden und die Ergebnisse als neue Liste zurückerhalten möchten, ohne die ursprüngliche Liste zu beeinflussen.Verwenden
forEach
Sie diese Option, wenn Sie anhand der einzelnen Elemente der Liste etwas tun möchten . Sie können der Seite beispielsweise Dinge hinzufügen. Im Wesentlichen ist es ideal, wenn Sie "Nebenwirkungen" wollen.Andere Unterschiede:
forEach
Gibt nichts zurück (da es sich wirklich um eine Kontrollflussfunktion handelt), und die übergebene Funktion erhält Verweise auf den Index und die gesamte Liste, während map die neue Liste zurückgibt und nur das aktuelle Element übergibt.quelle
ForEach versucht, eine Funktion wie das Schreiben in db usw. auf jedes Element der RDD anzuwenden, ohne etwas zurückzugeben.
Aber das
map()
wendet eine Funktion auf die Elemente von rdd an und gibt das rdd zurück. Wenn Sie also die folgende Methode ausführen, schlägt sie in Zeile 3 nicht fehl, aber beim Sammeln der Festplatte nach dem Anwenden von foreach schlägt sie fehl und es wird ein Fehler ausgegeben, der besagtquelle