javascript - javascript如何编写自己的`reduce` 函数?

我想自己写 reduce 。 但在过去的4个小时里,我无法做到。


var a = [10, 21, 13, 56];



function add(a, b) { return a + b }


function foo(a, b) { return a.concat(b) }



Array.prototype.reduce2 = function () {


//I do not understand how to handle the function of the inlet


//I know that I should use arguments, but I don't know how many arguments there will be


 var result = 0;


 for(var i = 0; i <arguments.length; i++) {


 result += arguments[i];


 }


 return result;


};



console.log(a.reduce(add), a.reduce2(add))//100 100


console.log(a.reduce(add, 10), a.reduce2(add, 10))//110 110



是的,我知道这似乎是很多话题,但我无法找到答案。 我缺少什么,或者在这里做错了?

时间:

主题中的数组不作为参数传递,而是上下文(this)。

还需要区分起始值的存在或者不存在:


var a = [10, 21, 13, 56];



function add(a, b) { return a + b }


function foo(a, b) { return a.concat(b) }



Array.prototype.reduce2 = function (f, result) {


 var i = 0;


 if (arguments.length <2) {


 i = 1;


 result = this[0];


 }


 for(; i <this.length; i++) {


 result = f(result, this[i], i, this);


 }


 return result;


};


console.log(a.reduce(add), a.reduce2(add))//100 100


console.log(a.reduce(add, 10), a.reduce2(add, 10))//110 110


//extra test with foo:


console.log(a.reduce(foo, 'X'), a.reduce2(foo, 'X'))//X10211356 X10211356

基于你的代码


var a = [10, 21, 13, 56];



function add(a, b) { return a + b }


function foo(a, b) { return a.concat(b) }



Array.prototype.reduce2 = function(fn, start){


 var result = start!== undefined? start : this[0];


 for (var i = 0; i <this.length; i++) {


 result = fn(result, this[i]);


 }


 return result;


};


console.log(a.reduce(add), a.reduce2(add))//100 100


console.log(a.reduce(add, 10), a.reduce2(add, 10))//110 110


console.log(a.reduce(foo, ''), a.reduce2(foo, ''));


console.log(a.reduce(foo, 'X'), a.reduce2(foo, 'X'));

我不确定我的答案是否正确回答了这个问题,但希望这能帮助某人。

不使用Prototype和循环的示例:


const origArr = [2,2]


const origFunc = (p,c) => p+c


const initial = 1



const reduce = (func, array, initial) => {


 const rec = (arr, acc) => {


//arr: [2, 2], [2], []


//acc: 1, 3, 5


 if (!arr.length) return acc


 const curr = arr[0]


 const nextArr = arr.slice(1)


 const nextAcc = func(acc, curr)


 return rec(nextArr, nextAcc)


 }


 if (initial) {


 return rec(array, initial)


 }


 return rec(array.slice(1), array[0])


}



console.log(origArr.reduce(origFunc, initial))//5


console.log(reduce(origFunc, origArr, initial))//5



带有循环的示例:


const reduceLoop = (func, array, initial) => {


 let acc = initial!== undefined? initial : array[0]


 let arr = initial!== undefined? [initial,.. .array] : array


 for(let i=1;i<arr.length;i++) {


 acc = func(acc, arr[i])


 }


 return acc


}



如你所见,在第一个示例中,我们没有分配变量,只有一些常量,但是在,中指定了 acc 变量。

下面的代码将传递的array 减少为单个值。 如果需要,需要传递一个关于数组和初始值的函数。


Array.prototype.myFunction = function(fn,initial) {


 let arayEl = this;


 console.log(arayEl);


 let total = initial || 0;


 for(let i=0;i<arayEl.length;i++) {


 total = fn(total,arayEl[i]);


 }


 return total;


}



console.log([1,2,3].myFunction(function(total,x){return total +x},10));


console.log([1,2,3].reduce(function(total,x){return total +x},10));


console.log([1,2,3].myFunction(function(total,x){return total * x},10));


console.log([1,2,3].reduce(function(total,x){return total * x},10));



  • 接受 custom的自定义reduce函数,它接受回调和初始值,该值为可选。 它会像reducer一样工作。
  • 向myFunction传递回调函数 function(total,x) {return total + x} 作为参数,然后将它的还原为单个值。 这里,我们可以执行任何操作,而不是添加。
...