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.assignke 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 reducearray. 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 reduceMetode membutuhkan dua parameter,
Array.prototype.reduce( callback, initialItem )
The callbackfungsi mengambil parameter berikut
(accumulator, itemInArray, indexInArray, entireArray) => { /* do stuff */ }
Untuk iterasi pertama,
Jika initialItemdisediakan, reducefungsi meneruskan initialItemsebagai accumulatordan item pertama dari array sebagai itemInArray.
Jika initialItemini tidak disediakan, reducefungsi melewati item pertama dalam array sebagai initialItemdan item kedua dalam array sebagai itemInArrayyang 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.