How to write your own `reduce` function?

I want to write reduce myself. But in the last 4 hours I could not.

 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 

Yes, I know this seems like a lot of topics, but I could not find the answer. What am I missing, or is something wrong here?

+6
source share
7 answers

An array in the subject is not passed as an argument, but is a context ( this ).

You also need to distinguish between the presence or absence of an initial value:

 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 
+5
source

Based on your code

 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')); 
+1
source

I'm not sure my answer exactly answers the question, but I hope this can help someone.

An example without using a prototype and loops:

 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 

And an example with a loop:

 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 } 

As you can see, in the first example we do not assign variables, we just have some constants, but in the loop example we assign the variable acc .

0
source

The code below reduces the passed array to a single value. It is necessary to pass a function about what should be done in the array and the initial value, if necessary.

 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)); 
  • myFunction is a custom reduction function that takes a callback function (fn) and an initial value, which is optional. This will work as a gearbox.
  • The function of the callBack (total, x) {return total + x} function is passed as a parameter to myFunction, which then reduces to a single value. Here, instead of adding, we can perform any operation, for example, reduce it.
0
source

 const reduceV1 = (list, cb, intial) => { let memo = intial; for (let i = 0; i < list.length; i++) { if (i === 0 && memo === undefined) { memo = list[0]; } else { memo = cb(list[i], memo); } } return memo; }; function sumV1(n, sum) { return n + sum; } console.log(reduceV1([1, 2], sumV1)); console.log(reduceV1([1, 2,3], sumV1,0)); 
0
source
 var a = [10, 21, 13, 56]; function add(a, b) { return a + b } Array.prototype.reduce2 = function(fn, start){ var result = start !== undefined ? start : this[0]; for (var i = 1; i < this.length; i++) { result = fn(result, this[i]); } return result; }; console.log(a.reduce(add), a.reduce2(add)) 
0
source

Actual decrease in function:

 const list = [1,2,3,4,5]; const sum = list => list.reduce((total, val)=> total+val, 0) console.log(sum(list)); 

If you look closely, we will need three things: a list for iteration, an initial value, and a reduction function

 const reduceHelper = (list, initialValue, reducer) => { // If the list is empty we will just return initial value if(list.length === 0) { return initialValue; } else { const [first, ...rest] = list; const updatedAcc = reducer(initialValue, first); return reduceHelper(rest, updatedAcc, reducer); } } // test it const list = [1,2,3,4,5]; console.log( myReduce(list, 0, (total, val) => total + val)) 

The idea is the same. We can follow the same idea and write another reduction function for word counting .......

0
source

Source: https://habr.com/ru/post/1259069/


All Articles