0

I want to write a recursive version of reduce function.

Array.prototype.reduce2 =
function reduce(fn, initial) {
 var head = this[0];
 var tail = this.slice(1);
 var result = fn(initial, head, 0, tail);
 return reduce(tail, fn, result);
}
var a = [1, 2, 3, 4];
function add(a, b) { return a + b } ;
function mul(a, b) { return a * b } ;
function foo(a, b) { return a.concat(b) };
console.log(a.reduce(add), a.reduce2(add)); // 10 10
console.log(a.reduce(add, 10), a.reduce2(add, 10)) ; // 20 20
console.log(a.reduce(add, undefined), a.reduce2(add, undefined)); // NaN NaN
console.log(a.reduce(mul), a.reduce2(mul)); // 24 24
console.log(a.reduce(foo, ''), a.reduce2(foo, '')); // 1234 123

The result was:

10 [Function: add]
20 [Function: add]
NaN [Function: add]
24 [Function: mul]
1234 function foo(a, b) { return a.concat(b) }

Yes, I know that this seems like a lot of topics, but I couldn't find answer.

asked Jan 22, 2018 at 12:25
1
  • 1
    Some things in your code don't make sense. Why do you call fn with 4 parameters when it only accepts 2? Your recursion has no stopping clause. You're calling reduce with 3 parameters when it accepts 2. Commented Jan 22, 2018 at 12:31

1 Answer 1

1

You should avoid adding methods to native objects.

You can do the same with a simple function in a simpler way using destructuring of the arguments.

function reduce(fn, initial, [head, ...tail]) {
 return tail.length
 ? reduce(fn, fn(initial, head), tail)
 : fn(initial, head)
}
Array.prototype.reduce2 = function(fn, initial) {
 const head = this[0]
 const tail = Array.prototype.slice.call(this, 1)
 return tail.length
 ? tail.reduce2(fn, fn(initial, head))
 : fn(initial, head)
}
const a = [1, 2, 3, 4];
const add = (a, b) => a + b
const mul = (a, b) => a * b
const foo = (a, b) => a.concat(b)
console.log(
 reduce(add, 0, a),
 a.reduce(add, 0),
 a.reduce2(add, 0)
)
console.log(
 reduce(mul, 1, a),
 a.reduce(mul, 1),
 a.reduce2(mul, 1)
)
console.log(
 reduce(foo, '', a),
 a.reduce(foo, ''),
 a.reduce2(foo, '')
)
console.assert(
 a.reduce2(add, 0) === 10,
 'reduce2 can sum numbers'
)
console.assert(
 a.reduce2(mul, 1) === 24,
 'reduce2 can multiply numbers'
)
console.assert(
 a.reduce2(foo, '') === '1234',
 'reduce2 can contatinate strings'
)
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js?tab=assert"></script>

answered Jan 22, 2018 at 12:53
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.