2

I'm trying to implement reduce() from scratch. I was able to get it working, but how does javascript know what "array" is even though I never defined it anywhere?

function reduce(callback, initialVal) {
  var accumulator = (initialVal === undefined) ? undefined : initialVal;
  for (var i=0; i<array.length; i++) {
    if (accumulator !== undefined) {
      accumulator = callback(accumulator, array[i], i, array);
    } else {
      accumulator = array[i]
    }
  }
  return accumulator;
};

// testing a basic sum
arr = [1,2,3]
arr.reduce( (accumulator, elem) => accumulator+=elem )

EDIT: I got it working :D I Changed 'array' to "this" since I was creating a new method under Array.prototype.

Array.prototype.myReduce = function(callback, initialVal) {
  var accumulator = (initialVal !== undefined) ? initialVal : undefined;
  for (var i=0; i<this.length; i++) {
    if (accumulator !== undefined) {
      accumulator = callback(accumulator, this[i], i, this);
    } else {
      accumulator = this[i]
    }
  }
  return accumulator;
};

arr.myReduce( (accumulator, elem) => accumulator+=elem )
arr.myReduce( (accumulator, elem) => accumulator+=elem , 100)
tbd_
  • 1,058
  • 1
  • 16
  • 39
  • you need to create [array.prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype).And also `array.reduce` overwrite the default js is bad practise.its affected the library of you are included.Better use different name instead js default – prasanth Apr 16 '19 at 02:51
  • Are you sure YOUR code is getting called and not built in `reduce` that is on `Array`'s `prototype`? – JohanP Apr 16 '19 at 02:51
  • `[` and `]` tells JS that it's an array – Anand G Apr 16 '19 at 02:51
  • Possible duplicate of [adding custom functions into Array.prototype](https://stackoverflow.com/questions/948358/adding-custom-functions-into-array-prototype) – prasanth Apr 16 '19 at 02:55
  • 1
    @prasanth you guys are right, it's most likely calling the native reduce() and not the one I just created...if I change the function to "myReduce()" it throws the error "TypeError: arr.myReduce is not a function". I'll retry by creating it under Array.prototype! – tbd_ Apr 16 '19 at 03:04

1 Answers1

12

You are pretty close. The one insight that seems to be missing is that inside your function, this will be defined as the array your function was called on. So you can use this in the places you're currently using array, which in your function will be undefined (as you suspected). You probably also want to start the loop in a different place depending on whether the initial value was passed in. For example:

function reduce(callback, initialVal) {
    var accumulator = ( initialVal === undefined) ? this[0] : initialVal;
    var start = (initialVal === undefined) ? 1 : 0
    for (var i = start; i < this.length; i++) {
        accumulator = callback(accumulator, this[i])
    }
    return accumulator;
  };

Array.prototype.myReduce = reduce

// no init value
console.log([1, 2, 3].myReduce((sum, curr) => sum + curr))

// init value:
console.log([1, 2, 3].myReduce((sum, curr) => sum + curr, 1000))
Mark
  • 90,562
  • 7
  • 108
  • 148