How to write JavaScript map, filter and reduce array methods from scratch

Basic implementation of map, filter & reduce methods from scratch.

·

3 min read

How to write JavaScript map, filter and reduce array methods from scratch

map

A method that runs the provided function on every item of an array and returns a new array.

const numbers = [ 1, 2, 3 ]

const doubleNumbers = numbers.map((num) => num * 2)

console.log(doubleNumbers)

// Output
// [ 2, 4, 6 ]

map basic implementation

Array.prototype._map = function(cbFunction) {
    const newArray = []

    for(let i = 0; i < this.length; i++) {
        const item = cbFunction(this[i], i, this)
        newArray.push(item)
    }

    return newArray;
}

const numbers = [ 1, 2, 3 ]
const doubleNumbers = numbers._map((num) => num * 2)
console.log(doubleNumbers)

// Output
// [ 2, 4, 6 ]
  • Here, we use the prototype to attach our custom method _map to the Array class.

  • _map accepts two arguments but here we are implementing the basic functionality of the map method.

  • Inside the custom _map method, we have access to the array using this keyword for which we apply the map method.

  • map method returns the same length array. So, we create a new array and run the loop for exact the length of the array.

  • Inside the loop, we call the passed function to the _map for each item (this[i]). Here this refers to the array.

  • cbFunction takes three arguments item, index and array.

  • return new array

filter

A method that runs the provided function on every item of an array and returns a new array containing only those items that return true on applying the callback function.

const numbers = [ 1, 2, 3, 4, 5, 6 ]

const evenNumbers = numbers.filter(n => n % 2 === 0)

console.log(evenNumbers)

// Output
// [ 2, 4, 6 ]

filter basic implementation

Array.prototype._filter = function(cbFunction) {
    const newArray = []

    for(let i = 0; i < this.length; i++) {
        if(!!cbFunction(this[i], i, this)) {
            newArray.push(this[i])
        }
    }

    return newArray
}

const numbers = [1,2,3,4,5,6]

const evenNumbers = numbers._filter(n => n % 2 === 0)

console.log(evenNumbers)

// Output
// [ 2, 4, 6]
  • same implementation as _map. Use the prototype to add a method _filter and pass cbFunction.

  • Inside the function loop the array and only add elements to the newArray if it returns true.

reduce

Apply the callback function to every element of the array and return a single value. On each callback call it returns accumulated value.

const numbers = [ 1, 2, 3, 4, 5, 6 ]

const sum = numbers.reduce((acc, cur, i) =>  acc + cur, 0)

console.log(sum)

// Output
// 21

reduce basic implementation

Array.prototype._reduce = function(cbFunction, initialValue) {
    let acc = initialValue

    if(this.length === 0 && initialValue === undefined) {
        throw new Error("Reduce of empty array with no initial value")
    }

    if(!initialValue) {
        if(typeof this[0] === "string") {
            acc = '';
        } else if(typeof this[0] === "number") {
            acc = 0;
        }
    }

    for(let i = 0; i < this.length; i++) {
        acc = cbFunction(acc, this[i], i)
    }

    return acc
}

const numbers = [ 1, 2, 3, 4, 5, 6 ]

const sum = numbers._reduce((acc, cur, i) => acc + cur, 0)

console.log(sum)

// Output
// 21
  • check if the array is empty and no initial value is passed then throw an error.

  • if no initialValue value is passed set it according to the type of first element of an array.

  • loop up to the array length and store the return value of cbFunction to acc (accumulator).

  • return acc.