reduce:累加器(accumulator)javascript
// 判斷非空
const isDef = function(o){
return o !== undefined && o !== null
}
/** * fn 函數 * @param { * } total 初始值(計算結束後的返回值) * @param { * } currentValue 當前元素 * @param { Number } currentIndex 當前元素的索引 * @param { Array } arr 當前元素所屬的數組對象 */
// Array的prototype聲明$reduce
Array.prototype.$reduce = function(fn, tar){
let len = this.length, // 目標數組長度
res, // 數組
i = 0; // 初始index
if (isDef(tar)) {
// 有第二個參數,total爲初始值
res = tar
} else {
// 沒有第二個參數,初始值爲數組第一項
res = this[0]
// 因爲第一項爲初始值,就從第二項開始累計
i++
}
// 循環數組
while (i < len) {
// 把算的值傳入fn第一個參數
res = fn(res, this[i], i++, this)
}
return res
}
複製代碼
應用java
[1, 2, 3, 4, 5].$reduce((total, currentValue, currentIndex, arr) => {
console.log(total, currentValue, currentIndex, arr)
return total + currentValue;
}, 0) // => 15
// 0 1 0 [ 1, 2, 3, 4, 5 ]
// 1 2 1 [ 1, 2, 3, 4, 5 ]
// 3 3 2 [ 1, 2, 3, 4, 5 ]
// 6 4 3 [ 1, 2, 3, 4, 5 ]
// 10 5 4 [ 1, 2, 3, 4, 5 ]
複製代碼
返回一個函數,把this改成返回函數的參數(arr)git
// reduce : ((a, b) → a) → a → [b] → a
const reduce = function(fn, tar){
const _isDef = function(o){
return o !== undefined && o !== null
}
return function(arr){
let len = arr.length,
res,
i = 0;
if (_isDef(tar)) {
res = tar
} else {
res = arr[0]
i++
}
while (i < len) {
res = fn(res, arr[i], i++, arr)
}
return res
}
}
// 求和
const sum = reduce((a, b) => a + b, 0)
sum([1, 2, 3, 4, 5]) // 15
// 求乘積
const product = reduce((a, b) => a * b)
product([1, 2, 3, 4, 5]) // 120
// 求對象數組某元素的某一項和
const inSum = reduce((a, { score }) => a + score, 0)
inSum([{ score: 1 }, { score: 2 }, { score: 3 }]) // 6
複製代碼
ps. 函數式編程最好的參考書: legacy.gitbook.com/book/llh911…編程