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?
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)
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.
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
.
-
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. Wszystkieforeach
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. Operacjamap
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. -
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
. map
moż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ą.
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.
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.
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.
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()
.
Edytowano 10-lis-2015: Dodano opracowanie.
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
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.
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