Czy jest jakaś różnica między foreachem a mapą?

Ok to jest bardziej pytanie informatyczne, niż pytanie oparte na konkretnym języku, ale czy jest różnica między operacją mapy a operacją foreach? Czy też są to po prostu różne nazwy dla tej samej rzeczy?

Author: hippietrail, 2008-12-10

8 answers

Inny.

Foreach iteruje nad listą i stosuje pewne operacje z efektami ubocznymi do każdego członka listy (np. zapisywanie każdego z nich do bazy danych)

Map iteruje nad listą, przekształca każdy element tej listy i zwraca inną listę tego samego rozmiaru z przekształconymi członkami (np. konwertuje listę łańcuchów na wielkie litery)

 277
Author: madlep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-10 02:14:53

Istotna różnica między nimi polega na tym, że map gromadzi wszystkie wyniki w zbiór, podczas gdy foreach nic nie zwraca. map jest zwykle używany, gdy chcesz przekształcić zbiór elementów za pomocą funkcji, podczas gdy foreach po prostu wykonuje akcję dla każdego elementu.

 111
Author: Henk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-10 02:15:31

W skrócie, foreach jest do zastosowania operacji na każdym elemencie zbioru elementów, podczas gdy {[1] } jest do przekształcenia jednego zbioru w inny.

Istnieją dwie istotne różnice między foreach i map.

  1. foreach nie ma pojęciowych ograniczeń co do operacji, którą stosuje, poza akceptacją elementu jako argumentu. Oznacza to, że operacja może nic nie robić, może mieć efekt uboczny, może zwracać wartość lub nie może zwracać wartości. Wszystkie foreach dba o to iterację nad zbiorem elementów i zastosowanie operacji na każdym elemencie.

    map, z drugiej strony, ma ograniczenia dotyczące operacji: oczekuje, że operacja zwróci element i prawdopodobnie również przyjmie element jako argument. Operacja map iteruje nad zbiorem elementów, stosując operację na każdym elemencie, a na koniec przechowuje wynik każdego wywołania operacji w innym zbiorze. Innymi słowy, map przekształca jeden zbiór w inny.

  2. foreach działa z pojedynczą kolekcją elementów. To jest kolekcja wejściowa.

    map działa z dwoma zbiorami elementów: zbiorem wejściowym i zbiorem wyjściowym.

Nie jest błędem powiązanie tych dwóch algorytmów: w rzeczywistości można zobaczyć te dwa hierarchicznie, gdzie map jest specjalizacją foreach. Czyli można użyć foreach i mieć operację przekształcającą jego argument i wstaw go do innej kolekcji. Algorytm foreach jest abstrakcją, uogólnieniem algorytmu map. W rzeczywistości, ponieważ foreach nie ma ograniczeń w swoim działaniu, możemy śmiało powiedzieć, że foreach jest najprostszym mechanizmem zapętlania i może zrobić wszystko, co może zrobić pętla. map, podobnie jak inne bardziej wyspecjalizowane algorytmy, istnieje ekspresja: jeśli chcesz zmapować (lub przekształcić) jedną kolekcję w inną, twoja intencja jest wyraźniejsza, jeśli użyjesz map niż jeśli używasz foreach.

Możemy rozszerzyć tę dyskusję i rozważyć algorytm copy: pętlę, która klonuje zbiór. Algorytm ten jest również specjalnością algorytmu foreach. Można zdefiniować operację, która, biorąc pod uwagę element, wstawi ten sam element do innej kolekcji. Jeśli użyjesz foreach z tą operacją, w efekcie wykonasz algorytm copy, aczkolwiek ze zmniejszoną klarownością, wyrazistością lub jaskrawością. Idźmy jeszcze dalej: możemy powiedzieć, że map to specjalizacja copy, sama w sobie specjalizacja foreach. mapmoże zmienić dowolny z elementów, nad którymi się iteracja. Jeśli map nie zmieni żadnego z elementów, to jedynie skopiuje elementy, a użycie skopiuje wyraziłoby intencję wyraźniej.

Sam algorytm foreach może mieć wartość zwracaną lub nie, w zależności od języka. Na przykład w C++, foreach zwraca operację, którą pierwotnie otrzymał. Chodzi o to, że operacja może mieć stan i możesz chcieć ją odzyskać, aby sprawdzić, jak ewoluowała w stosunku do elementów. map również może zwracać wartość. W C++ transform (odpowiednik map tutaj) zdarza się zwracać iterator na koniec kontenera wyjściowego (kolekcji). W Rubim wartość zwracana map jest sekwencją wyjściową (kolekcją). Tak więc, wartość zwracana algorytmów jest tak naprawdę szczegółem implementacji; ich efekt może być, ale nie musi być tym, co zwracają.

 40
Author: wilhelmtell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-28 23:53:40

Array.protototype.map metoda & Array.protototype.forEach są bardzo podobne.

Uruchom następujący kod: 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));
});

Dają dokładny wynik.

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

Ale twist pojawia się, gdy uruchamiasz następujący kod:-

tutaj po prostu przypisałem wynik zwracanej wartości z metod map i forEach.

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();

Teraz wynik jest czymś 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

Podsumowanie

Array.prototype.map zwraca tablicę, ale Array.prototype.forEach nie. można więc manipulować zwracaną tablicą wewnątrz funkcji zwrotnej przekazanej do metody map, a następnie ją zwrócić.

Array.prototype.forEach tylko przechodzi przez podaną tablicę, dzięki czemu można robić swoje rzeczy podczas chodzenia tablicy.

 30
Author: abhisekp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-02 11:19:15

Najbardziej "widoczną" różnicą jest to, że map gromadzi wynik w nowym zbiorze, podczas gdy foreach jest wykonywany tylko dla samego wykonania.

Ale jest kilka dodatkowych założeń: ponieważ' celem ' map jest nowa lista wartości, nie ma znaczenia kolejność wykonania. w rzeczywistości niektóre środowiska wykonawcze generują równoległy kod, a nawet wprowadzają pewne memoizacje, aby uniknąć wywoływania powtarzających się wartości lub leniwości, aby uniknąć wywoływania niektórych w wszystkie.

Foreach, z drugiej strony, jest nazywany specjalnie dla skutków ubocznych; dlatego kolejność jest ważna i zwykle nie może być równoległa.

 11
Author: Javier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-25 15:52:46

Krótka odpowiedź: map i forEach są różne. Ponadto, nieformalnie mówiąc, {[5] } jest ścisłym supersetem forEach.

Długa odpowiedź: najpierw wymyślmy jedną linijkę opisów forEach i map:

  • forEach iteracja wszystkich elementów, wywołanie dostarczonej funkcji na każdym z nich.
  • map iteracja wszystkich elementów, wywołanie dostarczonej funkcji na każdym i tworzy przekształconą tablicę, zapamiętując wynik każdej funkcji sprawdzam.

W Wielu Językach, forEach jest często nazywany po prostu each. Poniższa dyskusja używa JavaScript tylko w celach informacyjnych. To może być każdy inny język.

Teraz użyjmy każdej z tych funkcji.

Używając forEach:

Zadanie 1: napisz funkcję printSquares, która przyjmuje tablicę liczb arr i wypisuje kwadrat każdego elementu w niej.

Rozwiązanie 1:

var printSquares = function (arr) {
    arr.forEach(function (n) {
        console.log(n * n);
    });
};

Używając map:

Zadanie 2: napisz funkcję selfDot, która przyjmuje tablicę liczb arr i zwraca tablicę, w której każdy element jest kwadratem odpowiadającego mu elementu w arr.

Na marginesie: tutaj, w slangu, staramy się wyrównać tablicę wejściową. Formalnie rzecz biorąc, staramy się obliczyć ze sobą produkt kropkowy.

Rozwiązanie 2:

var selfDot = function (arr) {
    return arr.map(function (n) {
        return n * n;
    });
};

Jak to jest map superset forEach?

Możesz użyć map do rozwiązania obu zadań, Zadanie 1 i Zadanie 2 . Jednak nie można użyć forEach do rozwiązania Zadania 2.

W roztwór 1 , jeśli po prostu zastąpisz forEach przez map, rozwiązanie nadal będzie ważne. W roztwór 2 jednak zastąpienie map przez forEach spowoduje złamanie wcześniej działającego roztworu.

forEach w kategoriach map:

Innym sposobem uświadomienia sobie wyższości map jest zaimplementowanie forEach w kategoriach map. Jako, że jesteśmy dobrymi programistami, nie będziemy ulegać w przestrzeni nazw. Zadzwonimy do naszego forEach, po prostu each.

Array.prototype.each = function (func) {
    this.map(func);
};

Teraz, jeśli nie lubisz prototype nonsens, proszę bardzo:

var each = function (arr, func) {
    arr.map(func); // Or map(arr, func);
};
Więc, umm.. Dlaczego forEach w ogóle istnieje?

Odpowiedzią jest efektywność. Jeśli nie jesteś zainteresowany przekształceniem tablicy w inną tablicę, dlaczego powinieneś obliczyć przekształconą tablicę? Tylko po to, żeby to wyrzucić? Oczywiście, że nie! Jeśli nie chcesz transformacji, nie powinieneś jej robić.

Więc podczas gdy mapa może być używana do rozwiąż Zadanie 1 , prawdopodobnie nie powinno. dla każdego jest odpowiedni kandydat do tego.


Oryginalna odpowiedź:

Chociaż w dużej mierze zgadzam się z odpowiedzią @madlep, chciałbym zaznaczyć, że map() jest ścisłym super-zestawem zforEach().

Tak, map() jest zwykle używany do tworzenia nowej tablicy. Jednak, może również być użyte do zmiany bieżącej tablicy.

Oto przykład:]}
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!!"]

W powyższym przykładzie a było wygodnie ustaw tak, że a[i] === i Dla i < a.length. Mimo to, demonstruje moc map().

Oto oficjalny opis map(). Zauważ, że map() może nawet zmienić tablicę, na której jest wywoływana! Hail map().

Mam nadzieję, że to pomogło.

Edytowano 10-lis-2015: Dodano opracowanie.

 11
Author: Sumukh Barve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-10 15:27:03

Oto przykład użycia list w Scali: map zwraca listę, foreach nie zwraca nic.

def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit

Tak więc map zwraca listę wynikającą z zastosowania funkcji f do każdego elementu listy:

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 stosuje f do każdego elementu:

scala> var sum = 0
sum: Int = 0

scala> list foreach (sum += _)

scala> sum
res2: Int = 6 // res1 is empty
 3
Author: irudyak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-13 07:56:27

Jeśli mówimy w szczególności o Javascript, różnica polega na tym, że map Jest funkcją pętli, podczas gdy forEach jest iteratorem.

Użyj map, gdy chcesz zastosować operację do każdego członka listy i uzyskać wyniki jako nową listę, bez wpływu na oryginalną listę.

Użyj forEach, gdy chcesz ZROBIĆ coś na podstawie każdego elementu listy. Możesz na przykład dodawać rzeczy do strony. Zasadniczo jest to idealne rozwiązanie, gdy chcesz "skutki uboczne".

Inne różnice: forEach nie zwraca nic (ponieważ w rzeczywistości jest to funkcja sterowania przepływem), a funkcja przekazywana otrzymuje odwołania do indeksu i całej listy, podczas gdy map zwraca nową listę i przechodzi tylko w bieżącym elemencie.

 2
Author: phyzome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-10 02:19:28