Ini adalah jawaban tambahan untuk membantu menjelaskan peta dan lipatan. Untuk contoh di bawah ini, saya akan menggunakan daftar ini. Ingat, daftar ini tidak dapat diubah, sehingga tidak akan pernah berubah:
var numbers = [1, 2, 3, 4, 5]
Saya akan menggunakan angka dalam contoh saya karena mereka menyebabkan kode mudah dibaca. Ingat juga, lipatan dapat digunakan untuk apa pun yang dapat digunakan untuk loop imperatif tradisional.
Sebuah peta mengambil daftar sesuatu, dan fungsi, dan mengembalikan daftar yang telah dimodifikasi menggunakan fungsi. Setiap item diteruskan ke fungsi, dan menjadi apa pun fungsi kembali.
Contoh termudah dari ini adalah hanya menambahkan nomor ke setiap nomor dalam daftar. Saya akan menggunakan pseudocode untuk menjadikannya agnostik bahasa:
function add-two(n):
return n + 2
var numbers2 =
map(add-two, numbers)
Jika Anda mencetak numbers2
, Anda akan melihat daftar [3, 4, 5, 6, 7]
mana yang pertama dengan 2 ditambahkan ke setiap elemen. Perhatikan fungsi add-two
itu diberikan kepadamap
untuk digunakan.
Lipatan serupa, kecuali fungsi yang Anda harus berikan harus mengambil 2 argumen. Argumen pertama biasanya akumulator (dalam lipatan kiri, yang paling umum). Akumulator adalah data yang dilewati saat perulangan. Argumen kedua adalah item saat ini dari daftar; seperti di atas untuk map
fungsi.
function add-together(n1, n2):
return n1 + n2
var sum =
fold(add-together, 0, numbers)
Jika Anda mencetak, sum
Anda akan melihat jumlah dari daftar angka: 15.
Inilah yang harus dilakukan argumen fold
:
Ini adalah fungsi yang kami beri lipatan. Lipatan akan melewati fungsi akumulator saat ini, dan item saat ini dari daftar. Apapun fungsi yang dikembalikan akan menjadi akumulator baru, yang akan diteruskan ke fungsi lain kali. Ini adalah bagaimana Anda "mengingat" nilai ketika Anda mengulang gaya FP. Saya memberinya fungsi yang mengambil 2 angka dan menambahkannya.
Ini adalah akumulator awal; apa akumulator mulai seperti sebelum item dalam daftar diproses. Saat Anda menjumlahkan angka, berapa totalnya sebelum Anda menambahkan angka apa pun? 0, yang saya sampaikan sebagai argumen kedua.
Terakhir, seperti halnya peta, kami juga memasukkan daftar angka untuk diproses.
Jika lipatan masih tidak masuk akal, pertimbangkan ini. Ketika Anda menulis:
# Notice I passed the plus operator directly this time,
# instead of wrapping it in another function.
fold(+, 0, numbers)
Anda pada dasarnya menempatkan fungsi yang diteruskan antara setiap item dalam daftar, dan menambahkan akumulator awal ke kiri atau kanan (tergantung pada apakah itu lipatan kiri atau kanan), jadi:
[1, 2, 3, 4, 5]
Menjadi:
0 + 1 + 2 + 3 + 4 + 5
^ Note the initial accumulator being added onto the left (for a left fold).
Yang sama dengan 15.
Gunakan map
ketika Anda ingin mengubah satu daftar menjadi daftar lain, dengan panjang yang sama.
Gunakan fold
ketika Anda ingin mengubah daftar menjadi nilai tunggal, seperti menjumlahkan daftar angka.
Sebagaimana @Jorg tunjukkan dalam komentar, "nilai tunggal" tidak perlu sesuatu yang sederhana seperti angka; bisa berupa objek tunggal, termasuk daftar atau tupel! Cara saya sebenarnya memiliki lipatan klik untuk saya adalah dengan mendefinisikan peta dalam bentuk lipatan. Perhatikan bagaimana akumulator adalah daftar:
function map(f, list):
fold(
function(xs, x): # xs is the list that has been processed so far
xs.add( f(x) ) # Add returns the list instead of mutating it
, [] # Before any of the list has been processed, we have an empty list
, list)
Jujur, begitu Anda memahami masing-masing, Anda akan menyadari bahwa hampir semua perulangan dapat diganti dengan lipatan atau peta.