TL; DR, tetapkan nilai awal
Menggunakan destrrukturisasi
arr.reduce( ( sum, { x } ) => sum + x , 0)
Tanpa merusak
arr.reduce( ( sum , cur ) => sum + cur.x , 0)
Dengan naskah
arr.reduce( ( sum, { x } : { x: number } ) => sum + x , 0)
Mari kita coba metode penghancuran:
const arr = [ { x: 1 }, { x: 2 }, { x: 4 } ]
const result = arr.reduce( ( sum, { x } ) => sum + x , 0)
console.log( result ) // 7
Kunci untuk ini adalah menetapkan nilai awal. Nilai kembali menjadi parameter pertama dari iterasi berikutnya.
Teknik yang digunakan dalam jawaban atas tidak idiomatis
Jawaban yang diterima mengusulkan TIDAK melewati nilai "opsional". Ini salah, karena cara idiomatik adalah bahwa parameter kedua selalu disertakan. Mengapa? Tiga alasan:
1. Berbahaya
- Tidak melewatkan nilai awal berbahaya dan dapat membuat efek samping dan mutasi jika fungsi panggilan balik ceroboh.
Melihat
const badCallback = (a,i) => Object.assign(a,i)
const foo = [ { a: 1 }, { b: 2 }, { c: 3 } ]
const bar = foo.reduce( badCallback ) // bad use of Object.assign
// Look, we've tampered with the original array
foo // [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ]
Namun jika kita melakukannya dengan cara ini, dengan nilai awal:
const bar = foo.reduce( badCallback, {})
// foo is still OK
foo // { a: 1, b: 2, c: 3 }
Sebagai catatan, kecuali jika Anda bermaksud untuk bermutasi objek asli, atur parameter pertama Object.assign
ke objek kosong. Seperti ini: Object.assign({}, a, b, c)
.
2 - Inferensi Jenis Yang Lebih Baik - Saat
menggunakan alat seperti Typecript atau editor seperti VS Code, Anda mendapatkan manfaat dari memberitahu kompiler awal dan dapat menangkap kesalahan jika Anda melakukannya dengan salah. Jika Anda tidak menetapkan nilai awal, dalam banyak situasi mungkin tidak dapat menebak dan Anda bisa berakhir dengan kesalahan runtime menyeramkan.
3 - Hormati Functors
- JavaScript bersinar terbaik saat anak fungsional dalamnya dilepaskan. Dalam dunia fungsional, ada standar tentang bagaimana Anda "melipat" atau reduce
array. Ketika Anda melipat atau menerapkan katamorfisme ke array, Anda mengambil nilai array itu untuk membangun tipe baru. Anda perlu mengkomunikasikan tipe yang dihasilkan - Anda harus melakukan ini bahkan jika tipe terakhir adalah nilai-nilai dalam array, array lain, atau jenis lainnya.
Mari kita pikirkan dengan cara lain. Dalam JavaScript, fungsi dapat diedarkan seperti data, ini adalah cara kerja callback, apa hasil dari kode berikut?
[1,2,3].reduce(callback)
Apakah akan mengembalikan nomor? Sebuah Objek? Ini membuatnya lebih jelas
[1,2,3].reduce(callback,0)
Baca lebih lanjut tentang spesifikasi pemrograman fungsional di sini: https://github.com/fantasyland/fantasy-land#foldable
Lebih banyak latar belakang
The reduce
Metode membutuhkan dua parameter,
Array.prototype.reduce( callback, initialItem )
The callback
fungsi mengambil parameter berikut
(accumulator, itemInArray, indexInArray, entireArray) => { /* do stuff */ }
Untuk iterasi pertama,
Jika initialItem
disediakan, reduce
fungsi meneruskan initialItem
sebagai accumulator
dan item pertama dari array sebagai itemInArray
.
Jika initialItem
ini tidak disediakan, reduce
fungsi melewati item pertama dalam array sebagai initialItem
dan item kedua dalam array sebagai itemInArray
yang dapat membingungkan perilaku.
Saya mengajar dan merekomendasikan untuk selalu menetapkan nilai awal pengurangan.
Anda dapat melihat dokumentasi di:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Semoga ini membantu!
arr.reduce(function(a,b){return a + b})
dalam contoh kedua.