Ok, jest to raczej pytanie informatyczne niż pytanie oparte na konkretnym języku, ale czy istnieje różnica między operacją mapowania a operacją foreach? A może są to po prostu różne nazwy dla tej samej rzeczy?
foreach
language-agnostic
computer-science
map-function
Robert Gould
źródło
źródło
Iterator[String]
odscala.io.Source.fromFile("/home/me/file").getLines()
i zastosuję się.foreach(s => ptintln(s))
do niego, zostanie wydrukowane dobrze, ale zaraz potem się opróżni. Jednocześnie, jeśli się.map(ptintln(_))
o to ubiegam - po prostu robi się pusty i nic nie jest drukowane.Odpowiedzi:
Różne.
foreach wykonuje iterację po liście i stosuje pewne operacje z efektami ubocznymi do każdego członka listy (na przykład zapisując każdego z nich w bazie danych)
map iteruje listę, przekształca każdy element tej listy i zwraca kolejną listę o tym samym rozmiarze z transformowanymi elementami (np. konwersję listy ciągów na wielkie litery)
źródło
map
ma nie doprowadzić do realizacji swojej podstawowej logiki aż po przekształcona lista spodziewane jest wezwany. Natomiastforeach
operacja jest obliczana natychmiast.Ważna różnica między nimi polega na tym, że
map
kumuluje wszystkie wyniki w kolekcji, aforeach
nic nie zwraca.map
jest zwykle używany, gdy chcesz przekształcić zbiór elementów za pomocą funkcji, podczas gdyforeach
po prostu wykonuje akcję dla każdego elementu.źródło
W skrócie,
foreach
służy do zastosowania operacji na każdym elemencie zbioru elementów, podczas gdymap
służy do przekształcenia jednej kolekcji w drugą.Istnieją dwie znaczące różnice między
foreach
imap
.foreach
nie ma pojęciowych ograniczeń dotyczących stosowanej operacji, poza tym, że może przyjąć element jako argument. Oznacza to, że operacja może nic nie robić, może mieć efekt uboczny, może zwrócić wartość lub może nie zwrócić wartości. Wszystkieforeach
dba o to, aby iteracyjne nad zbiór elementów i zastosować operację na każdym elemencie.map
z drugiej strony ma ograniczenie operacji: oczekuje, że operacja zwróci element i prawdopodobnie również zaakceptuje element jako argument.map
Działanie iteracje przez zbiór elementów, stosowanie operacji na każdym elemencie i na koniec przechowywanie wyniku każdego wywołania działania do innego zbioru. Innymi słowy,map
przekształca jedną kolekcję w drugą.foreach
współpracuje z pojedynczą kolekcją elementów. To jest kolekcja danych wejściowych.map
współpracuje z dwoma kolekcjami elementów: kolekcją wejściową i kolekcją wyjściową.Odwoływanie się do dwóch algorytmów nie jest błędem: w rzeczywistości można je zobaczyć hierarchicznie, gdzie
map
jest specjalizacjaforeach
. Oznacza to, że możesz użyćforeach
operacji i przekształcić jej argument i wstawić go do innej kolekcji. Tak więc,foreach
algorytm jest abstrakcją, uogólnienie, zmap
algorytmu. W rzeczywistości, ponieważforeach
nie ma ograniczeń w jego działaniu, możemy śmiało powiedzieć, żeforeach
jest to najprostszy dostępny mechanizm zapętlania i może on wykonywać wszystko, co może zrobić pętla.map
, podobnie jak inne bardziej wyspecjalizowane algorytmy, służy ekspresji: jeśli chcesz zmapować (lub przekształcić) jedną kolekcję w inną, twoja intencja jest wyraźniejsza, jeśli używasz,map
niż używaszforeach
.Możemy rozszerzyć tę dyskusję i rozważyć
copy
algorytm: pętlę, która klonuje kolekcję. Ten algorytm też jest specjalizacjąforeach
algorytmu. Możesz zdefiniować operację, która przy danym elemencie wstawi ten sam element do innej kolekcji. Jeśli korzystaszforeach
z tej operacji, w rzeczywistości wykonałeścopy
algorytm, choć ze zmniejszoną jasnością, ekspresją lub wyraźnością. Przejdźmy jeszcze dalej: możemy powiedzieć, żemap
jest to specjalizacjacopy
sama w sobieforeach
.map
może zmienić dowolny z iterowanych elementów. Jeślimap
nie zmienia żadnego z elementów, to po prostu skopiował elementy i używał kopiowania wyraźniej wyraziłby to zamiar.Sam
foreach
algorytm może, ale nie musi, mieć wartość zwracaną, w zależności od języka. Na przykład w C ++foreach
zwraca pierwotnie otrzymaną operację. Chodzi o to, że operacja może mieć stan i możesz chcieć, aby ta operacja wróciła, aby sprawdzić, jak ewoluowała nad elementami.map
, również może, ale nie musi, zwrócić wartość. W C ++transform
(odpowiednikmap
tutaj) zdarza się, że zwraca iterator na końcu kontenera wyjściowego (kolekcji). W Ruby zwracaną wartościąmap
jest sekwencja wyjściowa (kolekcja). Zatem zwracana wartość algorytmów jest naprawdę szczegółem implementacji; ich efekt może, ale nie musi, być tym, co zwracają.źródło
.forEach()
można.map()
znaleźć tutaj: stackoverflow.com/a/39159854/1524693Array.protototype.map
metoda iArray.protototype.forEach
oba są dość podobne.Uruchom następujący kod: http://labs.codecademy.com/bw1/6#:workspace
Dają dokładny wynik ditto.
Ale zwrot pojawia się po uruchomieniu następującego kodu:
Tutaj po prostu przypisałem wynik wartości zwracanej z mapy i metod forEach.
Teraz wynik jest trudny!
Wniosek
Array.prototype.map
zwraca tablicę, aleArray.prototype.forEach
nie. Możesz więc manipulować zwróconą tablicą wewnątrz funkcji wywołania zwrotnego przekazanej do metody map, a następnie zwrócić ją.Array.prototype.forEach
tylko przechodzi przez podaną tablicę, więc możesz robić swoje rzeczy podczas chodzenia po tablicy.źródło
najbardziej „widoczną” różnicą jest to, że mapa akumuluje wynik w nowej kolekcji, podczas gdy foreach jest wykonywany tylko dla samego wykonania.
ale istnieje kilka dodatkowych założeń: ponieważ „celem” mapy jest nowa lista wartości, tak naprawdę nie ma znaczenia kolejność wykonywania. w rzeczywistości niektóre środowiska wykonawcze generują kod równoległy, a nawet wprowadzają pewne zapamiętywanie, aby uniknąć wywoływania powtarzających się wartości lub lenistwa, aby w ogóle nie wywoływać niektórych.
foreach, z drugiej strony, jest nazywany specjalnie dla skutków ubocznych; dlatego kolejność jest ważna i zwykle nie można jej sparaliżować.
źródło
Krótka odpowiedź:
map
iforEach
są różne. Ponadto, mówiąc nieformalnie,map
jest to ścisły nadzórforEach
.Długa odpowiedź: najpierw wymyślmy opisy jednej linii
forEach
imap
:forEach
iteruje wszystkie elementy, wywołując dostarczoną funkcję na każdym z nich.map
iteruje wszystkie elementy, wywołując podaną funkcję na każdym z nich, i tworzy transformowaną tablicę zapamiętując wynik każdego wywołania funkcji.W wielu językach
forEach
jest często nazywany po prostueach
. Poniższa dyskusja używa JavaScript tylko w celach informacyjnych. To może być naprawdę dowolny inny język.Teraz użyjmy każdej z tych funkcji.
Używanie
forEach
:Zadanie 1: Napisz funkcję
printSquares
, która akceptuje tablicę liczbarr
i drukuje w niej kwadrat każdego elementu.Rozwiązanie 1:
Używanie
map
:Zadanie 2: Napisz funkcję
selfDot
, która akceptuje tablicę liczbarr
i zwraca tablicę, w której każdy element jest kwadratem odpowiedniego elementu warr
.Poza tym: tutaj, w slangu, próbujemy wyrównać tablicę wejściową. Formalnie rzecz biorąc, staramy się obliczyć sam produkt kropkowy.
Rozwiązanie 2:
Jak działa
map
nadzbiórforEach
?Możesz użyć
map
do rozwiązania obu zadań, zadania 1 i zadania 2 . Nie można jednak użyćforEach
do rozwiązania zadania 2 .W roztworze 1 , jeśli po prostu zastąpić
forEach
przezmap
roztwór będą nadal ważne. Jednak w rozwiązaniu 2 zastąpieniemap
przezforEach
spowoduje uszkodzenie wcześniej działającego rozwiązania.Realizacja
forEach
w zakresiemap
:Innym sposobem uświadomienia sobie
map
wyższości jest wdrożenieforEach
w kategoriachmap
. Ponieważ jesteśmy dobrymi programistami, nie pozwolimy sobie na zanieczyszczenie przestrzeni nazw. Zadzwonimy do naszegoforEach
, tylkoeach
.Teraz, jeśli nie lubisz
prototype
bzdur, proszę:Więc umm .. Dlaczego w
forEach
ogóle istnieje?Odpowiedzią jest wydajność. Jeśli nie jesteś zainteresowany transformacją tablicy w inną tablicę, dlaczego powinieneś obliczyć transformowaną tablicę? Tylko rzucić to? Oczywiście nie! Jeśli nie chcesz transformacji, nie powinieneś jej przekształcać.
Tak więc chociaż mapę można wykorzystać do rozwiązania zadania 1 , prawdopodobnie nie powinna. Każdy bowiem jest do tego odpowiednim kandydatem.
Oryginalna odpowiedź:
Podczas gdy w większości zgadzają się z @madlep „s odpowiedzi, chciałbym podkreślić, że
map()
jest to ścisłe super zestaw zforEach()
.Tak,
map()
zwykle służy do tworzenia nowej tablicy. Można go jednak również użyć do zmiany bieżącej tablicy.Oto przykład:
W powyższym przykładzie
a
został dogodnie ustawiony tak, żea[i] === i
dlai < a.length
. Mimo to pokazuje mocmap()
.Oto oficjalny opis
map()
. Zauważ, żemap()
może nawet zmienić tablicę, na której się nazywa! Gradmap()
.Mam nadzieję, że to pomogło.
Edytowano 10-lis-2015: Dodano opracowanie.
źródło
map
funkcję, ale nieforEach
; nie możesz po prostu nie użyćmap
zamiastforEach
? Z drugiej strony, jeśli język miałby,forEach
ale niemap
, musiałbyś wdrożyć własnymap
. Nie można po prostu użyćforEach
zamiastmap
. Powiedz mi co myślisz.Oto przykład w Scali z wykorzystaniem list: mapa zwraca listę, foreach nic nie zwraca.
Zatem mapa zwraca listę wynikającą z zastosowania funkcji f do każdego elementu listy:
Foreach po prostu stosuje się do każdego elementu:
źródło
Jeśli mówisz w szczególności o Javascript, różnica jest taka
map
jest to funkcja pętli, podczasforEach
gdy iterator.Posługiwać się
map
gdy chcesz zastosować operację do każdego członka listy i uzyskać wyniki z powrotem jako nową listę, bez wpływu na oryginalną listę.Użyj,
forEach
kiedy chcesz zrobić coś na podstawie każdego elementu listy. Możesz na przykład dodawać elementy do strony. Zasadniczo jest to świetne, gdy chcesz uzyskać „skutki uboczne”.Inne różnice:
forEach
powraca nic (ponieważ jest to naprawdę funkcją przepływu sterowania), a przekazywana w funkcji staje się odniesienia do indeksu i całej listy, podczas gdy map Zwraca nową listę i przekazuje tylko w bieżącym elemencie.źródło
ForEach próbuje zastosować funkcję, taką jak zapis do db itp. Na każdym elemencie RDD bez zwracania czegokolwiek.
Ale
map()
stosuje pewną funkcję do elementów rdd i zwraca rdd. Więc kiedy uruchomisz poniższą metodę, nie zawiedzie ona na linii 3, ale podczas zbierania RDD po zastosowaniu Foreach nie powiedzie się i wyrzuci błąd, który mówi:źródło