参考链接:
https://www.cnblogs.com/art-poet/p/12522669.html
https://www.runoob.com/jsref/jsref-reduce.html
1. 原函数返回结果:
let arr = [1, 2, 3, 4];
const fn = (pre, cur, index, arr) => {
console.log(pre, cur, index, arr);
return pre + cur;
};
let result = arr.reduce(fn, 0);
console.log(result);
/*
0 1 0 [ 1, 2, 3, 4 ]
1 2 1 [ 1, 2, 3, 4 ]
3 3 2 [ 1, 2, 3, 4 ]
6 4 3 [ 1, 2, 3, 4 ]
10
*/
2.粗略版:
/*
实现思路:
深拷贝出一个新数组,首先将初始值放入数组最前,然后将数组的前两位传入函数fn进行运算,
不断将函数fn的计算结果放入到最前面,并删除原先的前两个数
*/
Array.prototype.reduceTest1 = function (fn, initValue) {
let initArr = this;
const arr = JSON.parse(JSON.stringify(initArr));
arr.unshift(initValue || 0);
let index;
while (arr.length > 2) {
index = initArr.length - arr.length + 1;
let newVal = fn(arr[0], arr[1], index, initArr);
arr.splice(0, 2);
arr.unshift(newVal);
}
return fn(arr[0], arr[1], ++index, initArr);
}
2. 升级版
/*
实现思路:
通过splice简化上面函数
*/
Array.prototype.reduceTest2 = function (fn, initValue) {
let initArr = this;
const arr = JSON.parse(JSON.stringify(initArr));
arr.unshift(initValue || 0);
let index, newVal;
while (arr.length > 1) {
index = initArr.length - arr.length + 1;
newVal = fn(arr[0], arr[1], index, initArr);
arr.splice(0, 2, newVal);
}
return newVal;
}
3. 递归版
/*
实现思路:
深拷贝出新的数组,因为只需返回累加值,所以递归过程只需将每层的累加值(fn的运算结果)依次往下传,最终将累加值返回即可
*/
Array.prototype.reduceTest3 = function (fn, initValue) {
const initArr = this;
const arr = JSON.parse(JSON.stringify(initArr));
return initValue ? helper(fn, initValue, -1, arr) : helper(fn, 0, -1, arr);
function helper (fn, acc, index, arr) { // acc累加值
if (arr.length === 0) return acc;
++index;
return helper(fn, fn(acc, arr.shift(), index, initArr), index, arr);
}
}
4.动态规划版
/*
实现思路:
递归过程的逆过程,动态规划函数:a(n+1)= f(a(n), initArr[i], i, arr)
*/
Array.prototype.reduceTest4 = function (fn, initValue) {
const initArr = this;
if (!initArr) return 0;
let acc = initValue || 0;
const len = initArr.length;
for (let i = 0; i < len; i++) {
acc = fn(acc, initArr[i], i, initArr);
}
return acc;
}