TL; DR, đặt giá trị ban đầu
Sử dụng phá hủy
arr.reduce( ( sum, { x } ) => sum + x , 0)
Không phá hủy
arr.reduce( ( sum , cur ) => sum + cur.x , 0)
Với bản đánh máy
arr.reduce( ( sum, { x } : { x: number } ) => sum + x , 0)
Hãy thử phương pháp phá hủy:
const arr = [ { x: 1 }, { x: 2 }, { x: 4 } ]
const result = arr.reduce( ( sum, { x } ) => sum + x , 0)
console.log( result ) // 7
Chìa khóa cho việc này là thiết lập giá trị ban đầu. Giá trị trả về trở thành tham số đầu tiên của lần lặp tiếp theo.
Kỹ thuật được sử dụng trong câu trả lời hàng đầu không phải là thành ngữ
Câu trả lời được chấp nhận đề xuất KHÔNG vượt qua giá trị "tùy chọn". Điều này là sai, vì cách thành ngữ là tham số thứ hai luôn được đưa vào. Tại sao? Ba lý do:
1. Nguy hiểm
- Không vượt qua giá trị ban đầu là nguy hiểm và có thể tạo ra tác dụng phụ và đột biến nếu chức năng gọi lại không cẩn thận.
Hãy chứng kiến
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 } ]
Tuy nhiên, nếu chúng tôi đã làm theo cách này, với giá trị ban đầu:
const bar = foo.reduce( badCallback, {})
// foo is still OK
foo // { a: 1, b: 2, c: 3 }
Đối với bản ghi, trừ khi bạn có ý định thay đổi đối tượng ban đầu, hãy đặt tham số đầu tiên của Object.assign
một đối tượng trống. Như thế này : Object.assign({}, a, b, c)
.
2 - Suy luận loại tốt hơn -
Khi sử dụng một công cụ như Typecript hoặc trình soạn thảo như VS Code, bạn sẽ nhận được lợi ích khi nói với trình biên dịch ban đầu và nó có thể bắt lỗi nếu bạn làm sai. Nếu bạn không đặt giá trị ban đầu, trong nhiều trường hợp, nó có thể không đoán được và bạn có thể gặp phải lỗi thời gian chạy đáng sợ.
3 - Tôn trọng Functor
- JavaScript tỏa sáng nhất khi chức năng bên trong của nó được giải phóng. Trong thế giới chức năng, có một tiêu chuẩn về cách bạn "gấp" hoặc reduce
một mảng. Khi bạn gấp hoặc áp dụng một catamorphism để mảng, bạn mất các giá trị của mảng đó để xây dựng một kiểu mới. Bạn cần giao tiếp với loại kết quả - bạn nên làm điều này ngay cả khi loại cuối cùng là của các giá trị trong mảng, mảng khác hoặc bất kỳ loại nào khác.
Hãy nghĩ về nó theo một cách khác. Trong JavaScript, các hàm có thể được chuyển xung quanh như dữ liệu, đây là cách gọi lại hoạt động, kết quả của mã sau đây là gì?
[1,2,3].reduce(callback)
Nó sẽ trả về một số? Một đối tượng? Điều này làm cho nó rõ ràng hơn
[1,2,3].reduce(callback,0)
Đọc thêm về thông số kỹ thuật lập trình tại đây: https://github.com/fantasyland/fantasy-land# Foldable
Một số nền tảng
Các reduce
phương pháp có hai tham số,
Array.prototype.reduce( callback, initialItem )
Các callback
chức năng có các thông số sau
(accumulator, itemInArray, indexInArray, entireArray) => { /* do stuff */ }
Đối với lần lặp đầu tiên,
Nếu initialItem
được cung cấp, reduce
hàm sẽ chuyển initialItem
như là accumulator
và mục đầu tiên của mảng là itemInArray
.
Nếu initialItem
là không được cung cấp, các reduce
chức năng vượt qua mục đầu tiên trong mảng như initialItem
và mục thứ hai trong mảng như itemInArray
có thể gây nhầm lẫn hành vi.
Tôi dạy và đề nghị luôn luôn thiết lập giá trị ban đầu của giảm.
Bạn có thể kiểm tra tài liệu tại:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Hi vọng điêu nay co ich!
arr.reduce(function(a,b){return a + b})
trong ví dụ thứ hai.