Gibt es einen Unterschied zwischen foreach und Karte?
-
21-08-2019 - |
Frage
Ok das ist eher eine Frage der Informatik, als eine Frage nach einer bestimmten Sprache basierte, aber gibt es einen Unterschied zwischen einer Karte Operation und einem foreach Betrieb? Oder sind sie einfach verschiedene Namen für die gleiche Sache?
Lösung
Verschiedene.
foreach iteriert über eine Liste und wendet eine Operation mit Nebenwirkungen auf jede Liste Element (wie jedes in die Datenbank zum Beispiel Speicher)
Karte iteriert über eine Liste transformiert jedes Mitglied der Liste, und gibt eine weitere Liste von gleicher Größe mit den transformierten Elementen (wie beispielsweise eine Liste von Zeichenfolge der Umwandlung in Großbuchstaben)
Andere Tipps
Der wichtige Unterschied zwischen ihnen ist, dass map
alle Ergebnisse in einer Sammlung sammelt, während foreach
nichts zurückgibt. map
ist in der Regel verwendet, wenn Sie eine Sammlung von Elementen mit einer Funktion zu transformieren wollen, während foreach
einfach eine Aktion für jedes Element ausgeführt wird.
Kurz gesagt, foreach
ist auf jedes Element einer Sammlung von Elementen, das einen Betrieb der Anwendung, während map
zum Transformieren einer Sammlung in eine andere ist.
Es gibt zwei wesentliche Unterschiede zwischen foreach
und map
.
-
foreach
hat keine konzeptionellen Einschränkungen für den Betrieb gilt, außer vielleicht ein Element als Argument akzeptieren. Das heißt, die Operation nichts tun, einen Nebeneffekt haben kann, kann einen Wert zurückgeben oder kann keinen Wert zurück. Alleforeach
kümmert sich um ist über eine Sammlung von Elementen zu durchlaufen, und wenden Sie den Vorgang für jedes Element.map
, auf der anderen Seite, hat auf dem Betrieb eine Beschränkung hat: es ist der Betrieb erwartet ein Element zurückzukehren, und wahrscheinlich auch ein Element als Argument akzeptieren. Diemap
Operation iteriert über eine Sammlung von Elementen für jedes Element, das den Betrieb der Anwendung, und schließlich das Ergebnis jeder Aufruf der Operation in einer anderen Sammlung speichert. Mit anderen Worten, verwandelt sich diemap
eine Sammlung in eine andere. -
foreach
arbeitet mit einer einzigen Sammlung von Elementen. Dies ist der Eingang Sammlung.map
arbeitet mit zwei Sammlungen von Elementen. Der Eingang Sammlung und der Ausgang Sammlung
Es ist kein Fehler, die beiden Algorithmen beziehen: In der Tat, können Sie die zwei hierarchisch zu sehen, wo map
eine Spezialisierung von foreach
ist. Das heißt, Sie foreach
verwenden könnten und haben den Betrieb sein Argument verwandeln und in einer anderen Sammlung einfügen. So ist der foreach
Algorithmus eine Abstraktion, eine Verallgemeinerung des map
Algorithmus. In der Tat, weil foreach
keine Beschränkung auf den Betrieb hat, kann man sicher sagen, dass foreach
die einfachste Looping Mechanismus gibt, und es kann eine Schleife tun alles tun kann. map
sowie andere mehr spezialisierte Algorithmen, gibt es für die Ausdruckskraft. Wenn Sie zuordnen möchten (oder Transformation) eine Sammlung in eine andere, Ihre Absicht ist es klarer, wenn Sie map
verwenden, als wenn Sie foreach
verwenden
Wir können diese Diskussion weiter ausbauen, und betrachten die copy
Algorithmus: eine Schleife, die eine Sammlung klont. Dieser Algorithmus ist auch eine Spezialisierung des foreach
Algorithmus. Sie könnten eine Operation, die, da ein Element definieren, wird das gleiche Element in einer anderen Sammlung einfügen. Wenn Sie foreach
mit dieser Operation verwenden in Sie Effekt ausgeführt, um den copy
Algorithmus, wenn auch mit reduzierter Klarheit, Ausdruckskraft oder Eindeutigkeit. Nehmen wir es noch weiter: Wir können sagen, dass map
eine Spezialisierung von copy
ist, sich eine Spezialisierung von foreach
. map
kann Veränderung alle Elemente es iteriert. Wenn map
eines der Elemente nicht ändern Sie dann es nur kopiert die Elemente, und mit Kopie würde drücken die Absicht deutlicher.
Der foreach
Algorithmus selbst kann oder auch nicht einen Rückgabewert hat, abhängig von der Sprache. In C ++ zum Beispiel foreach
gibt den Betrieb ursprünglich empfangen. Die Idee ist, dass der Betrieb einen Zustand haben könnte, und Sie können diese Operation wollen zurück zu untersuchen, wie es über die Elemente entwickelt. map
Auch zurückkehren kann oder nicht Wert. In C ++ transform
(das Äquivalent für map
hier) passiert, einen Iterator auf das Ende des Ausgangsbehälters (collection) zurückzukehren. In Ruby, ist der Rückgabewert von map
die Ausgangssequenz (Sammlung). So ist der Rückgabewert der Algorithmen wirklich eine Implementierung Detail; ihre Wirkung kann oder kann nicht sein, was sie zurückkehren.
Array.protototype.map
Methode & Array.protototype.forEach
sind beide sehr ähnlich.
Führen Sie den folgenden Code: http://labs.codecademy.com/bw1/6#:workspace
var arr = [1, 2, 3, 4, 5];
arr.map(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
});
console.log();
arr.forEach(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
});
Sie geben das genaue dito Ergebnis.
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
Aber die Wendung kommt, wenn Sie den folgenden Code ausführen: -
Hier habe ich einfach das Ergebnis der Rückgabewert von der Karte und forEach Methoden zugewiesen haben.
var arr = [1, 2, 3, 4, 5];
var ar1 = arr.map(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
return val;
});
console.log();
console.log(ar1);
console.log();
var ar2 = arr.forEach(function(val, ind, arr){
console.log("arr[" + ind + "]: " + Math.pow(val,2));
return val;
});
console.log();
console.log(ar2);
console.log();
Jetzt ist das Ergebnis etwas tricky!
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
[ 1, 2, 3, 4, 5 ]
arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25
undefined
Fazit
Array.prototype.map
gibt ein Array aber Array.prototype.forEach
nicht. So können Sie das zurückgegebene Array innerhalb der Callback-Funktion auf die Karte Methode übergeben manipulieren und sie dann zurück.
Array.prototype.forEach
geht nur durch das angegebene Array, so dass Sie Ihre Sachen tun können, während das Array zu Fuß.
der ‚sichtbar‘ Unterschied ist, dass Karte das Ergebnis in einer neuen Kollektion ansammelt, während foreach nur für die Ausführung erfolgte selbst.
, aber es gibt ein paar zusätzliche Annahmen: Da der ‚Zweck‘ der Karte die neue Liste der Werte ist, ist es nicht wirklich die Reihenfolge der Ausführung zählt. in der Tat erzeugen einige Ausführungsumgebungen parallel Code oder sogar einige memoizing zu vermeiden, für die wiederholte Werte aufrufen oder lazyness einführen, rufen einige gar zu vermeiden.
foreach, auf der anderen Seite, ist speziell für die Nebenwirkungen genannt; daher ist die Reihenfolge wichtig, und in der Regel nicht parallelisiert werden.
Kurze Antwort: map
und forEach
unterschiedlich sind. Auch informell gesprochen, map
ist eine strenge Obermenge von forEach
.
Lange Antwort: Lassen Sie sich zuerst kommt mit einer Zeile Beschreibungen von forEach
und map
:
-
forEach
iteriert über alle Elemente, die bereitgestellte Funktion auf jedem Aufruf. -
map
iteriert über alle Elemente, die bereitgestellte Funktion auf jeden Aufruf und erzeugt eine transformierte Matrix durch das Ergebnis jeden Funktionsaufruf zu erinnern.
In vielen Sprachen forEach
oft nur each
genannt wird. Die folgende Diskussion verwendet JavaScript nur Referenz. Es könnte wirklich eine andere Sprache sein.
Nun lassen Sie uns jede dieser Funktionen verwendet werden.
Mit forEach
:
Task 1: eine Funktion printSquares
schreiben, die eine Reihe von Zahlen arr
annimmt, und druckt das Quadrat von jedem Element darin
Lösung 1:
var printSquares = function (arr) {
arr.forEach(function (n) {
console.log(n * n);
});
};
Mit map
:
Task. 2: Schreibe eine Funktion selfDot
, die eine Reihe von Zahlen arr
annimmt, und gibt einen Array, wobei jedes Element das Quadrat des entsprechenden Elements in arr
Neben: Hier in umgangssprachlichen Begriffen, wir versuchen, die Eingabe-Array zu quadrieren. Formal setzen, versuchen wir es mit sich selbst Punktprodukt zu berechnen.
Lösung 2:
var selfDot = function (arr) {
return arr.map(function (n) {
return n * n;
});
};
Wie ist map
ein Superset von forEach
?
Sie können map
verwenden, um beide Aufgaben zu lösen, Aufgabe 1 und Task 2 . Sie können jedoch nicht forEach
verwenden lösen Sie die Aufgabe 2 .
Lösung 1 , wenn Sie einfach forEach
durch map
ersetzen, wird die Lösung noch gültig sein. In Lösung 2 jedoch map
durch forEach
ersetzt wird Ihre zuvor funktionierende Lösung brechen.
Die Implementierung forEach
in Bezug auf map
:
Eine weitere Möglichkeit map
Überlegenheit zu realisieren ist forEach
in Bezug auf map
zu implementieren. Da wir gute Programmierer sind, werden wir nicht in Namespace Verschmutzung frönen. Wir werden unsere forEach
, nur each
nennen.
Array.prototype.each = function (func) {
this.map(func);
};
Wenn Sie nun den prototype
Unsinn nicht mögen, hier gehen Sie:
var each = function (arr, func) {
arr.map(func); // Or map(arr, func);
};
So, umm .. Warum die forEach
überhaupt?
Die Antwort ist Effizienz. Wenn Sie bei der Transformation ein Array in ein anderes Array nicht interessiert sind, warum sollten Sie die transformierten Array berechnen? Nur um es zu Dump? Natürlich nicht! Wenn Sie nicht über eine Transformation wollen, sollten Sie nicht eine Transformation tun.
Während also die Karte verwendet werden kann, lösen Aufgabe 1 , sollte es wahrscheinlich nicht. Für jeden ist der richtige Kandidat für das.
Original Antwort:
Während ich weitgehend mit @madlep ‚s Antwort zustimmen, würde Ich mag darauf hinweisen, dass map()
ist ein strenge Super-Set von forEach()
.
Ja, map()
in der Regel verwendet, um ein neues Array zu erstellen. Allerdings kann es auch verwendet werden, um die aktuelle Array zu ändern.
Hier ist ein Beispiel:
var a = [0, 1, 2, 3, 4], b = null;
b = a.map(function (x) { a[x] = 'What!!'; return x*x; });
console.log(b); // logs [0, 1, 4, 9, 16]
console.log(a); // logs ["What!!", "What!!", "What!!", "What!!", "What!!"]
Im obigen Beispiel wurde a
bequem so eingestellt, dass a[i] === i
für i < a.length
. Trotzdem ist es demonstriert die Macht des map()
.
Hier ist die offizielle Beschreibung von map()
. Beachten Sie, dass map()
kann sogar das Array ändern, auf dem sie aufgerufen wird! Hagel map()
.
Hoffe, dass dies geholfen hat.
Edited 10-Nov-2015:. Hinzugefügt Ausarbeitung
Hier ist ein Beispiel in Scala mit Listen: Kartenliste zurückgibt, foreach gibt nichts zurück.
def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit
So Karte gibt die Liste aus der Anwendung der Funktion f auf jedes Listenelement:
scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)
scala> list map (x => x * 2)
res0: List[Int] = List(2, 4, 6)
Foreach gilt nur f für jedes Element:
scala> var sum = 0
sum: Int = 0
scala> list foreach (sum += _)
scala> sum
res2: Int = 6 // res1 is empty
Wenn Sie sprechen Javascript insbesondere der Unterschied ist, dass map
eine Loop-Funktion während forEach
ein Iterator ist.
Verwenden map
wenn Sie eine Operation an jedes Mitglied der Liste anwenden mögen, und die Ergebnisse zurück als eine neue Liste zu bekommen, ohne die ursprüngliche Liste zu beeinflussen.
Verwenden Sie forEach
, wenn Sie möchten, tun etwas auf der Basis jedes Element der Liste. Sie könnten die Dinge auf der Seite, zum Beispiel hinzufügen. Im Wesentlichen ist es großartig, wenn Sie „Nebenwirkungen“ wollen.
Weitere Unterschiede: forEach
nichts gibt (da es wirklich ein Ablauffunktionskontrolle ist), und die übergebene Funktion erhält Verweise auf den Index und die gesamte Liste, während Karte die neue Liste zurück und übergibt nur im aktuellen Element.
FürJeden versucht, eine Funktion wie das Schreiben zu db etc auf jedem Element des RDD anzuwenden, ohne wieder etwas zurück.
Aber die map()
gilt eine Funktion über die Elemente von rdd und gibt den rdd. Also wenn Sie die folgenden Verfahren ausführen wird es nicht bei line3 scheitern aber während der rdd sammeln nach foreach ihre Anwendung fehlschlagen und einen Fehler aus, die besagt,
Datei "
", Linie 5, in Attribute: 'NoneType' Objekt hat kein Attribut 'sammeln'
nums = sc.parallelize([1,2,3,4,5,6,7,8,9,10])
num2 = nums.map(lambda x: x+2)
print ("num2",num2.collect())
num3 = nums.foreach(lambda x : x*x)
print ("num3",num3.collect())