Kapan saya harus menggunakan reduceLeft
, reduceRight
, foldLeft
, foldRight
, scanLeft
atauscanRight
?
Saya ingin intuisi / gambaran perbedaan mereka - mungkin dengan beberapa contoh sederhana.
scala
scala-collections
reduce
fold
Marc Grue
sumber
sumber
reduce
danfold
BUKAN keberadaan nilai awal - lebih merupakan konsekuensi dari alasan matematika yang mendasari yang lebih mendalam.Jawaban:
Secara umum, semua 6 fungsi lipat berlaku operator biner untuk setiap elemen koleksi. Hasil dari setiap langkah diteruskan ke langkah berikutnya (sebagai input ke salah satu dari dua argumen operator biner). Dengan cara ini kita bisa mengumpulkan hasilnya.
reduceLeft
danreduceRight
mengumpulkan satu hasil.foldLeft
danfoldRight
mengumpulkan satu hasil menggunakan nilai awal.scanLeft
danscanRight
mengumpulkan kumpulan hasil kumulatif antara menggunakan nilai awal.Mengumpulkan
Dari KIRI dan ke depan ...
Dengan kumpulan elemen
abc
dan operator biner,add
kita dapat menjelajahi apa fungsi lipatan yang berbeda dilakukan saat beralih dari elemen LEFT koleksi (dari A ke C):Dari KANAN dan mundur ...
Jika kita mulai dengan elemen KANAN dan mundur (dari C ke A) kita akan melihat bahwa sekarang yang kedua argumen ke operator biner kita mengakumulasi hasilnya (operatornya sama, kita hanya mengganti nama argumen untuk memperjelas peran mereka. ):
.
De-kumulasi
Dari KIRI dan ke depan ...
Jika sebaliknya kami harus melakukan de-kumulasi beberapa hasil dengan mengurangi mulai dari elemen LEFT koleksi, kami akan mengumpulkan hasil melalui argumen pertama
res
dari operator biner kamiminus
:Dari KANAN dan mundur ...
Tapi lihat variasi xRight sekarang! Ingat bahwa (de-) nilai terakumulasi dalam variasi xRight diteruskan ke parameter kedua
res
dari operator biner kamiminus
:Daftar terakhir (-2, 3, -1, 4, 0) mungkin bukan yang Anda harapkan secara intuitif!
Seperti yang Anda lihat, Anda dapat memeriksa apa yang dilakukan foldX Anda dengan hanya menjalankan scanX dan men-debug hasil yang terakumulasi pada setiap langkah.
Intinya
reduceLeft
ataureduceRight
.foldLeft
ataufoldRight
jika Anda memiliki nilai awal.Mengumpulkan kumpulan hasil antara dengan
scanLeft
atauscanRight
.Gunakan variasi xLeft jika Anda ingin meneruskan koleksi.
sumber
List
untuk kemudian diterapkanfoldLeft
. Koleksi lain dapat menerapkan strategi yang berbeda. Secara umum, jikafoldLeft
danfoldRight
dapat digunakan secara bergantian (properti asosiatif dari operator yang diterapkan), makafoldLeft
lebih efisien dan disukai.Biasanya MENGURANGI, FOLD, metode SCAN bekerja dengan mengumpulkan data pada LEFT dan terus mengubah variabel KANAN. Perbedaan utama di antara mereka adalah REDUCE, FOLD adalah: -
Lipat akan selalu dimulai dengan
seed
nilai yaitu nilai awal yang ditentukan pengguna. Reduce akan membuang pengecualian jika koleksi kosong di mana lipatan mengembalikan nilai benih. Akan selalu menghasilkan nilai tunggal.Pemindaian digunakan untuk beberapa pemrosesan urutan item dari sisi kiri atau kanan, maka kita dapat menggunakan hasil sebelumnya dalam perhitungan selanjutnya. Itu artinya kita dapat memindai item. Akan selalu menghasilkan koleksi.
RIGHT_REDUCE berlawanan dengan mengurangiLeft satu yaitu mengakumulasi nilai dalam KANAN dan terus mengubah variabel kiri.
MengurangiLeftOpsi dan MengurangiRightOpsi mirip dengan perbedaan hanya left_reduce dan right_reduce adalah mereka mengembalikan hasil dalam objek OPTION.
Bagian dari output untuk kode yang disebutkan di bawah ini adalah: -
menggunakan
scan
operasi di atas daftar angka (menggunakanseed
nilai0
)List(-2,-1,0,1,2)
{0, -2} => - 2 {-2, -1} => - 3 {-3,0} => - 3 {-3,1} => - 2 {-2,2} => 0 Daftar pindaian (0, -2, -3, -3, -2, 0)
{0, -2} => - 2 {-2, -1} => - 3 {-3,0} => - 3 {-3,1} => - 2 {-2,2} => 0 scanLeft (a + b) Daftar (0, -2, -3, -3, -2, 0)
{0, -2} => - 2 {-2, -1} => - 3 {-3,0} => - 3 {-3,1} => - 2 {-2,2} => 0 scanLeft (b + a) Daftar (0, -2, -3, -3, -2, 0)
{2,0} => 2 {1,2} => 3 {0,3} => 3 {-1,3} => 2 {-2,2} => 0 scanRight (a + b) Daftar ( 0, 2, 3, 3, 2, 0)
{2,0} => 2 {1,2} => 3 {0,3} => 3 {-1,3} => 2 {-2,2} => 0 scanRight (b + a) Daftar ( 0, 2, 3, 3, 2, 0)
menggunakan
reduce
,fold
operasi atas daftar StringsList("A","B","C","D","E")
Kode:
sumber
Untuk koleksi x dengan elemen x0, x1, x2, x3 dan fungsi arbitrer untuk Anda memiliki yang berikut:
Kesimpulannya
scan
sepertifold
tetapi juga memancarkan semua nilai perantarareduce
tidak memerlukan nilai awal yang kadang-kadang sedikit lebih sulit ditemukanfold
membutuhkan nilai awal yang sedikit lebih sulit ditemukan:x.reduceLeft(f) === x.drop(1).foldLeft(x.head,f)
x.foldRight(init,f) === x.reverse.foldLeft(init,f)
x.foldLeft(init,f) === x.scanLeft(init,f).last
sumber