tbd_
tbd_

Reputation: 1248

Implementing reduce() from scratch, not sure how JS knows what "array" is

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)

Upvotes: 4

Views: 5411

Answers (2)

Pratik Salgiya
Pratik Salgiya

Reputation: 1

Crips and clear

Array.prototype.myReduce = function (callback, iterator) {
    // Initialize the iterator based on the type of the first element
    if (typeof this[0] === "number" && iterator === undefined) {
        iterator = 0;
    } else if (typeof this[0] === "string" && iterator === undefined) {
        iterator = "";
    }

    // Iterate through the array and apply the callback
    for (let i = 0; i < this.length; i++) {
        iterator = callback(iterator, this[i]);
    }

    return iterator; // Return the final accumulated value
};

Upvotes: 0

Mark
Mark

Reputation: 92440

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))

Upvotes: 15

Related Questions