Ok ini lebih merupakan pertanyaan sains komputer, daripada pertanyaan berdasarkan bahasa tertentu, tetapi apakah ada perbedaan antara operasi peta dan operasi foreach? Atau apakah mereka hanya nama yang berbeda untuk hal yang sama?
foreach
language-agnostic
computer-science
map-function
Robert Gould
sumber
sumber
Iterator[String]
dariscala.io.Source.fromFile("/home/me/file").getLines()
dan menerapkannya.foreach(s => ptintln(s))
, itu dicetak ok tapi menjadi kosong setelahnya. Pada saat yang sama jika saya menerapkannya.map(ptintln(_))
- itu hanya menjadi kosong dan tidak ada yang dicetak.Jawaban:
Berbeda.
foreach iterates atas daftar dan menerapkan beberapa operasi dengan efek samping untuk setiap anggota daftar (seperti menyimpan masing-masing ke database misalnya)
peta iterasi di atas daftar, mengubah setiap anggota daftar itu, dan mengembalikan daftar lain dengan ukuran yang sama dengan anggota yang diubah (seperti mengonversi daftar string menjadi huruf besar)
sumber
map
tidak tidak menghasilkan eksekusi logika yang mendasarinya sampai kapan daftar mengubah diharapkan dipanggil. Sebaliknya,foreach
operasi dihitung segera.Perbedaan penting di antara mereka adalah bahwa
map
semua hasil terakumulasi menjadi koleksi, sedangkanforeach
tidak mengembalikan apa pun.map
biasanya digunakan ketika Anda ingin mengubah kumpulan elemen dengan fungsi, sedangkanforeach
hanya menjalankan aksi untuk setiap elemen.sumber
Singkatnya,
foreach
adalah untuk menerapkan operasi pada setiap elemen dari kumpulan elemen, sedangkanmap
untuk mengubah satu koleksi menjadi yang lain.Ada dua perbedaan signifikan antara
foreach
danmap
.foreach
tidak memiliki batasan konseptual pada operasi yang berlaku, selain dari mungkin menerima elemen sebagai argumen. Artinya, operasi mungkin tidak melakukan apa-apa, mungkin memiliki efek samping, dapat mengembalikan nilai atau mungkin tidak mengembalikan nilai. Yang perluforeach
diperhatikan adalah beralih pada kumpulan elemen, dan menerapkan operasi pada setiap elemen.map
, di sisi lain, memang memiliki batasan pada operasi: ia mengharapkan operasi untuk mengembalikan elemen, dan mungkin juga menerima elemen sebagai argumen. Themap
Operasi iterates atas kumpulan elemen, menerapkan operasi pada setiap elemen, dan akhirnya menyimpan hasil setiap permintaan dari operasi menjadi koleksi lain. Dengan kata lain,map
mengubah satu koleksi menjadi yang lain.foreach
bekerja dengan satu kumpulan elemen. Ini adalah koleksi input.map
bekerja dengan dua koleksi elemen: koleksi input dan koleksi output.Ini bukan kesalahan untuk menghubungkan kedua algoritma: pada kenyataannya, Anda dapat melihat keduanya secara hierarkis, di mana
map
ada spesialisasiforeach
. Artinya, Anda bisa menggunakanforeach
dan meminta operasi mengubah argumennya dan memasukkannya ke koleksi lain. Jadi,foreach
algoritma adalah abstraksi, generalisasi, darimap
algoritma. Faktanya, karenaforeach
tidak memiliki batasan pada operasinya, kita dapat dengan aman mengatakan bahwa ituforeach
adalah mekanisme perulangan yang paling sederhana di luar sana, dan ia dapat melakukan apa saja yang dapat dilakukan perulangan.map
, serta algoritme lain yang lebih terspesialisasi, tersedia untuk ekspresif: jika Anda ingin memetakan (atau mengubah) satu koleksi menjadi koleksi lain, niat Anda lebih jelas jika Anda gunakanmap
daripada jika Anda gunakanforeach
.Kami dapat memperluas diskusi ini lebih lanjut, dan mempertimbangkan
copy
algoritma: loop yang mengkloning koleksi. Algoritma ini juga merupakan spesialisasi dariforeach
algoritma. Anda bisa mendefinisikan operasi yang, diberikan elemen, akan memasukkan elemen yang sama ke koleksi lain. Jika Anda gunakanforeach
dengan operasi itu, Anda sebenarnya melakukancopy
algoritma, meskipun dengan kejelasan, ekspresif atau kejelasan yang berkurang. Mari kita bahas lebih jauh: Kita dapat mengatakan bahwa itumap
adalah spesialisasicopy
, itu sendiri adalah spesialisasiforeach
.map
dapat mengubah salah satu elemen yang diulangi. Jikamap
tidak mengubah salah satu elemen maka itu hanya menyalin elemen, dan menggunakan salinan akan mengekspresikan niat lebih jelas.The
foreach
algoritma itu sendiri mungkin atau mungkin tidak memiliki nilai kembali, tergantung pada bahasa. Di C ++, misalnya,foreach
mengembalikan operasi yang semula diterima. Idenya adalah bahwa operasi tersebut mungkin memiliki keadaan, dan Anda mungkin ingin operasi itu kembali untuk memeriksa bagaimana itu berevolusi atas elemen.map
, juga, mungkin atau mungkin tidak mengembalikan nilai. Dalam C ++transform
(setara dengan dimap
sini) terjadi untuk mengembalikan iterator ke akhir wadah keluaran (koleksi). Di Ruby, nilai balik darimap
adalah urutan keluaran (koleksi). Jadi, nilai balik dari algoritma ini benar-benar detail implementasi; efeknya mungkin atau mungkin bukan apa yang mereka kembalikan.sumber
.forEach()
dapat digunakan untuk mengimplementasikan.map()
, lihat di sini: stackoverflow.com/a/39159854/1524693Array.protototype.map
Metode &Array.protototype.forEach
keduanya sangat mirip.Jalankan kode berikut: http://labs.codecademy.com/bw1/6#:workspace
Mereka memberikan hasil yang tepat.
Namun twist datang ketika Anda menjalankan kode berikut: -
Di sini saya hanya menetapkan hasil dari nilai pengembalian dari peta dan metode forEach.
Sekarang hasilnya adalah sesuatu yang rumit!
Kesimpulan
Array.prototype.map
mengembalikan array tetapiArray.prototype.forEach
tidak. Jadi Anda dapat memanipulasi array yang dikembalikan di dalam fungsi callback yang diteruskan ke metode peta dan kemudian mengembalikannya.Array.prototype.forEach
hanya berjalan melalui array yang diberikan sehingga Anda dapat melakukan pekerjaan sambil berjalan di array.sumber
perbedaan yang paling 'terlihat' adalah bahwa peta mengakumulasikan hasil dalam koleksi baru, sementara foreach hanya dilakukan untuk eksekusi itu sendiri.
tetapi ada beberapa asumsi tambahan: karena 'tujuan' peta adalah daftar nilai baru, itu tidak terlalu penting urutan eksekusi. pada kenyataannya, beberapa lingkungan eksekusi menghasilkan kode paralel, atau bahkan memperkenalkan beberapa memoizing untuk menghindari panggilan untuk nilai yang berulang, atau kemalasan, untuk menghindari panggilan sama sekali.
foreach, di sisi lain, disebut khusus untuk efek samping; oleh karena itu urutannya penting, dan biasanya tidak dapat diparalelkan.
sumber
Jawaban singkat:
map
danforEach
berbeda. Juga, berbicara secara informal,map
adalah superset ketatforEach
.Jawaban panjang: Pertama, mari kita buat dengan satu baris deskripsi
forEach
danmap
:forEach
iterates atas semua elemen, memanggil fungsi yang disediakan pada masing-masing.map
iterates atas semua elemen, memanggil fungsi yang disediakan pada masing-masing, dan menghasilkan array yang diubah dengan mengingat hasil dari setiap panggilan fungsi.Dalam banyak bahasa,
forEach
sering disebut adileach
. Diskusi berikut menggunakan JavaScript hanya untuk referensi. Itu bisa benar-benar bahasa lain.Sekarang, mari kita gunakan masing-masing fungsi ini.
Menggunakan
forEach
:Tugas 1: Tulis fungsi
printSquares
, yang menerima array angkaarr
, dan mencetak kuadrat dari setiap elemen di dalamnya.Solusi 1:
Menggunakan
map
:Tugas 2: Tulis fungsi
selfDot
, yang menerima array angkaarr
, dan mengembalikan array di mana setiap elemen adalah kuadrat dari elemen yang sesuai diarr
.Selain: Di sini, dalam istilah slang, kami mencoba untuk menguadratkan array input. Secara formal, kami mencoba menghitung produk titik itu sendiri.
Solusi 2:
Bagaimana
map
supersetforEach
?Anda dapat menggunakan
map
untuk menyelesaikan kedua tugas, Tugas 1 dan Tugas 2 . Namun, Anda tidak dapat menggunakanforEach
untuk menyelesaikan Tugas 2 .Di Solusi 1 , jika Anda hanya menggantinya
forEach
denganmap
, solusi masih akan valid. Namun dalam Solusi 2 , menggantimap
denganforEach
akan merusak solusi Anda yang sebelumnya berfungsi.Melaksanakan
forEach
dalam halmap
:Cara lain untuk mewujudkan
map
keunggulan adalah dengan mengimplementasikannyaforEach
dalam halmap
. Karena kami adalah programmer yang baik, kami tidak akan terlibat dalam polusi namespace. Kami akan memanggil kamiforEach
, adileach
.Sekarang, jika Anda tidak suka
prototype
omong kosong, ini dia:Jadi, umm .. Kenapa
forEach
bahkan ada?Jawabannya adalah efisiensi. Jika Anda tidak tertarik mengubah array menjadi array lain, mengapa Anda harus menghitung array yang diubah? Hanya membuangnya? Tentu saja tidak! Jika Anda tidak ingin transformasi, Anda tidak harus melakukan transformasi.
Jadi, sementara peta dapat digunakan untuk menyelesaikan Tugas 1 , mungkin seharusnya tidak. Untuk masing-masing adalah kandidat yang tepat untuk itu.
Jawaban asli:
Sementara saya sebagian besar setuju dengan jawaban @madlep 's, saya ingin menunjukkan bahwa
map()
adalah super-set yang ketat dariforEach()
.Ya,
map()
biasanya digunakan untuk membuat array baru. Namun, ini juga dapat digunakan untuk mengubah array saat ini.Ini sebuah contoh:
Dalam contoh di atas,
a
mudah diatur sedemikian rupaa[i] === i
untuki < a.length
. Meski begitu, itu menunjukkan kekuatanmap()
.Berikut deskripsi resmi dari
map()
. Catatan yangmap()
bahkan dapat mengubah array yang disebut! Salammap()
.Semoga ini bisa membantu.
Diedit 10-Nov-2015: Menambahkan elaborasi.
sumber
map
fungsi asli tetapi tidakforEach
; tidak bisa Anda tidak menggunakanmap
bukanforEach
? Di sisi lain, jika suatu bahasa memilikiforEach
tetapi tidakmap
, Anda harus menerapkan bahasa Anda sendirimap
. Anda tidak bisa hanya menggunakanforEach
bukanmap
. Katakan padaku apa yang kau pikirkan.Berikut adalah contoh dalam Scala menggunakan daftar: daftar pengembalian peta, foreach mengembalikan apa-apa.
Jadi peta mengembalikan daftar yang dihasilkan dari penerapan fungsi f ke setiap elemen daftar:
Foreach hanya berlaku untuk setiap elemen:
sumber
Jika Anda berbicara tentang Javascript secara khusus, perbedaannya adalah
map
fungsi loop sedangkanforEach
iterator.Gunakan
map
ketika Anda ingin menerapkan operasi untuk setiap anggota daftar dan mendapatkan hasilnya kembali sebagai daftar baru, tanpa mempengaruhi daftar asli.Gunakan
forEach
ketika Anda ingin melakukan sesuatu berdasarkan setiap elemen daftar. Anda mungkin menambahkan hal-hal ke halaman, misalnya. Pada dasarnya, ini bagus untuk saat Anda menginginkan "efek samping".Perbedaan lainnya:
forEach
tidak mengembalikan apa-apa (karena ini benar-benar fungsi kontrol aliran), dan fungsi pass-in mendapatkan referensi ke indeks dan seluruh daftar, sedangkan peta mengembalikan daftar baru dan hanya lewat di elemen saat ini.sumber
ForEach mencoba menerapkan fungsi seperti menulis ke db dll pada setiap elemen RDD tanpa mengembalikan apa pun.
Tetapi
map()
menerapkan beberapa fungsi atas elemen rdd dan mengembalikan rdd. Jadi ketika Anda menjalankan metode di bawah ini tidak akan gagal di line3 tetapi saat mengumpulkan rdd setelah menerapkan foreach itu akan gagal dan melempar kesalahan yang mengatakansumber