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?
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?
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)
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, sedangkan foreach
tidak mengembalikan apa pun. map
biasanya digunakan ketika Anda ingin mengubah kumpulan elemen dengan fungsi, sedangkan foreach
hanya menjalankan aksi untuk setiap elemen.
Singkatnya, foreach
adalah untuk menerapkan operasi pada setiap elemen dari kumpulan elemen, sedangkan map
untuk mengubah satu koleksi menjadi yang lain.
Ada dua perbedaan signifikan antara foreach
dan map
.
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 perlu foreach
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. The map
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 spesialisasi foreach
. Artinya, Anda bisa menggunakan foreach
dan meminta operasi mengubah argumennya dan memasukkannya ke koleksi lain. Jadi, foreach
algoritma adalah abstraksi, generalisasi, dari map
algoritma. Faktanya, karena foreach
tidak memiliki batasan pada operasinya, kita dapat dengan aman mengatakan bahwa itu foreach
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 gunakan map
daripada jika Anda gunakan foreach
.
Kami dapat memperluas diskusi ini lebih lanjut, dan mempertimbangkan copy
algoritma: loop yang mengkloning koleksi. Algoritma ini juga merupakan spesialisasi dari foreach
algoritma. Anda bisa mendefinisikan operasi yang, diberikan elemen, akan memasukkan elemen yang sama ke koleksi lain. Jika Anda gunakan foreach
dengan operasi itu, Anda sebenarnya melakukan copy
algoritma, meskipun dengan kejelasan, ekspresif atau kejelasan yang berkurang. Mari kita bahas lebih jauh: Kita dapat mengatakan bahwa itu map
adalah spesialisasi copy
, itu sendiri adalah spesialisasi foreach
. map
dapat mengubah salah satu elemen yang diulangi. Jika map
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 di map
sini) terjadi untuk mengembalikan iterator ke akhir wadah keluaran (koleksi). Di Ruby, nilai balik dari map
adalah urutan keluaran (koleksi). Jadi, nilai balik dari algoritma ini benar-benar detail implementasi; efeknya mungkin atau mungkin bukan apa yang mereka kembalikan.
.forEach()
dapat digunakan untuk mengimplementasikan .map()
, lihat di sini: stackoverflow.com/a/39159854/1524693
Array.protototype.map
Metode & Array.protototype.forEach
keduanya sangat mirip.Jalankan kode berikut: 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));
});
Mereka memberikan hasil yang tepat.
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
Di sini saya hanya menetapkan hasil dari nilai pengembalian dari peta dan metode 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();
Sekarang hasilnya adalah sesuatu yang rumit!
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
Array.prototype.map
mengembalikan array tetapi Array.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.
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.
Jawaban singkat: map
dan forEach
berbeda. Juga, berbicara secara informal, map
adalah superset ketat forEach
.
Jawaban panjang: Pertama, mari kita buat dengan satu baris deskripsi forEach
dan map
:
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 adil each
. Diskusi berikut menggunakan JavaScript hanya untuk referensi. Itu bisa benar-benar bahasa lain.
Sekarang, mari kita gunakan masing-masing fungsi ini.
forEach
:Tugas 1: Tulis fungsi printSquares
, yang menerima array angka arr
, dan mencetak kuadrat dari setiap elemen di dalamnya.
Solusi 1:
var printSquares = function (arr) {
arr.forEach(function (n) {
console.log(n * n);
});
};
map
:Tugas 2: Tulis fungsi selfDot
, yang menerima array angka arr
, dan mengembalikan array di mana setiap elemen adalah kuadrat dari elemen yang sesuai di arr
.
Selain: Di sini, dalam istilah slang, kami mencoba untuk menguadratkan array input. Secara formal, kami mencoba menghitung produk titik itu sendiri.
Solusi 2:
var selfDot = function (arr) {
return arr.map(function (n) {
return n * n;
});
};
map
superset forEach
?Anda dapat menggunakan map
untuk menyelesaikan kedua tugas, Tugas 1 dan Tugas 2 . Namun, Anda tidak dapat menggunakan forEach
untuk menyelesaikan Tugas 2 .
Di Solusi 1 , jika Anda hanya menggantinya forEach
dengan map
, solusi masih akan valid. Namun dalam Solusi 2 , mengganti map
dengan forEach
akan merusak solusi Anda yang sebelumnya berfungsi.
forEach
dalam hal map
:Cara lain untuk mewujudkan map
keunggulan adalah dengan mengimplementasikannya forEach
dalam hal map
. Karena kami adalah programmer yang baik, kami tidak akan terlibat dalam polusi namespace. Kami akan memanggil kami forEach
, adil each
.
Array.prototype.each = function (func) {
this.map(func);
};
Sekarang, jika Anda tidak suka prototype
omong kosong, ini dia:
var each = function (arr, func) {
arr.map(func); // Or map(arr, func);
};
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.
Sementara saya sebagian besar setuju dengan jawaban @madlep 's, saya ingin menunjukkan bahwa map()
adalah super-set yang ketat dari forEach()
.
Ya, map()
biasanya digunakan untuk membuat array baru. Namun, ini juga dapat digunakan untuk mengubah array saat ini.
Ini sebuah contoh:
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!!"]
Dalam contoh di atas, a
mudah diatur sedemikian rupa a[i] === i
untuk i < a.length
. Meski begitu, itu menunjukkan kekuatan map()
.
Berikut deskripsi resmi darimap()
. Catatan yang map()
bahkan dapat mengubah array yang disebut! Salam map()
.
Semoga ini bisa membantu.
Diedit 10-Nov-2015: Menambahkan elaborasi.
map
fungsi asli tetapi tidak forEach
; tidak bisa Anda tidak menggunakan map
bukan forEach
? Di sisi lain, jika suatu bahasa memiliki forEach
tetapi tidak map
, Anda harus menerapkan bahasa Anda sendiri map
. Anda tidak bisa hanya menggunakan forEach
bukan map
. Katakan padaku apa yang kau pikirkan.
Berikut adalah contoh dalam Scala menggunakan daftar: daftar pengembalian peta, foreach mengembalikan apa-apa.
def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit
Jadi peta mengembalikan daftar yang dihasilkan dari penerapan fungsi f ke setiap elemen daftar:
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 hanya berlaku untuk setiap elemen:
scala> var sum = 0
sum: Int = 0
scala> list foreach (sum += _)
scala> sum
res2: Int = 6 // res1 is empty
Jika Anda berbicara tentang Javascript secara khusus, perbedaannya adalah map
fungsi loop sedangkan forEach
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.
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 mengatakan
File "<stdin>", baris 5, dalam <module>
AttributeError: objek 'NoneType' tidak memiliki atribut 'kumpulkan'
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())
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.