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.

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>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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.