JavaScript Array Methods Detailed Review of forEach() ,map , filter() and reduce()

Table of contents

Let’s first understand πŸ€” What is an Array?

Quoting from MDN directly.

The Array object, as with arrays in other programming languages, enables storing a collection of multiple items under a single variable name and has members for performing common array operations.

For example see this sample of code of JS

// 'kings' array created using array literal notation.
const kings = ['Ashoka', 'Samundragupta'];
console.log(kings.length);
// 2

Which specific Array Methods will we learn about?

  • forEach() method
  • map
  • filter
  • reduce

forEach() Method 😍

If for loop is a jack of all trades in looping over an array. And you hate having to iterate using index wishing if only there were easier ways.

forEach() is for the answer for you, it is a master of simplicity and easily understood code.

Syntax 😌

This is the syntax for using forEach() using arrow function.

forEach((element, index, array) => { /* ... */ })

Let’s understand the parameters in the syntax

  • callbackFn : Function which executes on each element
  • element : Current element being worked on in array.
  • index (Optional) : The index of element in array
  • array (Optional) : Array upon which forEach() was called .

Example Usage for looping over an array.

const arr=[
    {
        'name':'Aashirwad',
        'roll':4

    },
    {
        'name':'Pankaj',
        'roll':78

    },
    {
        'name':'Ayush',
        'roll':70

    },
    {
        'name':'Nisha',
        'roll':33

    },

]

arr.forEach(element => console.log(element));
// 
//   { name: 'Aashirwad', roll: 4 },
//   { name: 'Pankaj', roll: 78 },
//   { name: 'Ayush', roll: 70 },
//   { name: 'Nisha', roll: 33 }
//

Pros of forEach() 😏

  • Increases readability of Code eliminating the possibility of bugs
  • It is convenient because there is no need to dereference inside of the loop. So the risk of overrunning or underrunning is eliminated.

Cons of forEach() πŸ₯²

  • Can’t skip an item .i.e the array index counter will always increase by +1.
  • No reverse order traversals.
  • It does not mutate the array it is called on however callbackFn could.
  • It always returns the value undefined hence is not chainable.
  • There is no way to stop or break a forEach() loop ( like using break or return in for loop)

Gotchas! 😳

const wars = [2, 8, 5];
let sum = 0;

const sumWarFunction = async (a, b) => a + b;

wars.forEach(async (war) => {
  sum = await sumWarFunction(sum, war);
});

console.log(sum);

// Naively expected output: 18
// Actual output: 0

map method 😎

If forEach() was master of simplicity for looping over array.

map is the king of modifying the array. If you want to simply modify the content of the array in an easily debuggable and readable code map is the answer for this.

Syntax πŸ˜‹

Using arrow functions map can be implemented in this way.

map((element, index, array) => { /* ... */ })

Let’s understand the parameters in the syntax

  • callbackFn: Function which executes on each element and each time callbackFn is called returned value is added to the newArray
  • element: Current element being worked on in array.
  • index (optional): The index of element in array
  • array (optional): Array upon which map was called.

Return value :

A new array is returned with each element being the result of a callback function.

Example code using map method

const arr=[
    {
        'name':'Aashirwad',
        'roll':4

    },
    {
        'name':'Pankaj',
        'roll':78

    },
    {
        'name':'Ayush',
        'roll':70

    },
    {
        'name':'Nisha',
        'roll':33

    },

]

const map1 = arr.map(x => x.roll * 2);

console.log(map1)

// [
//   { name: 'Aashirwad', roll: 8 },
//   { name: 'Pankaj', roll: 146 },
//   { name: 'Ayush', roll: 140 },
//   { name: 'Nisha', roll: 66 }
// ]

Here we see that map is used not just to iterate over array but also the element of the array is modified in such a way that value is returned to a newArray.

When to use map πŸ’ͺ (Pros over forEach())

  • Since they return values in newArray they are chainable.
  • It is useful if the returned array is to be used.

When to not use map πŸ₯² (Cons)

  • If a new array returned is of no use, then it is silly to use the map
  • If the idea is to just iterate over values using forEach() is better.

Gotchas! 😳

Implementing Maps from scratch 😎

It takes in a callback function with array element and returns a new array with operation defined in return statement used during the function call.


const arr=[
    {
        'name':'Aashirwad',
        'roll':4

    },
    {
        'name':'Pankaj',
        'roll':78

    },
    {
        'name':'Ayush',
        'roll':70

    },
    {
        'name':'Nisha',
        'roll':33

    },

]
let mymap =(ar,callback)=>{
    const new_ar=[];
    ar.forEach((e) => {
        new_ar.push(callback(e))


    });
    return new_ar;

}

console.log(mymap(arr,(a)=>{
    return a.name
}))

// [ 'Aashirwad', 'Pankaj', 'Ayush', 'Nisha' ]

filter() method πŸ₯³

filter() is a kind of Mantri ( minister ) for kings, filtering out the elements before returning them in a newArray based on callbackFn returning only those values which satisfy a condition.

Syntax πŸ˜‡

This is the syntax for using filter() using arrow function.

filter((element, index, array) => { /* ... */ } )

Let’s understand the parameters in the syntax

  • callbackFn: Function is to test each element of the array and return a value that is either true to keep the element in newArray or false to not keep the element in the newArray.
  • element: Current element being worked on in array.
  • index (optional) : The index of element in array
  • array (optional) : Array upon which filter() was called .

Return value :

A new array is returned elements that pass the test defined in callbackFn.

Example Code using filter() method

const arr=[
    {
        'name':'Aashirwad',
        'roll':4

    },
    {
        'name':'Pankaj',
        'roll':78

    },
    {
        'name':'Ayush',
        'roll':70

    },
    {
        'name':'Nisha',
        'roll':33

    },

]

console.log(arr.filter(e => e.roll<20))

// [ { name: 'Aashirwad', roll: 4 } ]

Here we display only those elements on the console for which roll > 20. Thus filtering out other values.

Pros of filter() πŸ’«

  • As we are operating with the element of the array, there is no need to define any index. Thus simplifying the code.
  • No need of creating a new array to push elements.

Cons of filter() πŸ₯²

  • If the new array returned is of no use, then it is silly to use filter better to just print the values using looping and if condition.

Gotchas! 😳

Implementing filter() from scratch 😎

Filter, as the name tells is used to filter out values from array-based on certain conditions i.e push only those values in a new array that satisfy the given condition in the return statement.

const arr=[
    {
        'name':'Aashirwad',
        'roll':4

    },
    {
        'name':'Pankaj',
        'roll':78

    },
    {
        'name':'Ayush',
        'roll':70

    },
    {
        'name':'Nisha',
        'roll':33

    },

]

const myfilter= function(arr,callback){
    const filter_arr=[];
    arr.forEach((e)=>{
        if(callback(e)){
            filter_arr.push(e);
        }

    })

    return filter_arr;
}

console.log(myfilter(arr,(e)=>{
    return e.roll>4
}))

// [
//   { name: 'Pankaj', roll: 78 },
//   { name: 'Ayush', roll: 70 },
//   { name: 'Nisha', roll: 33 }
// ]

reduce() method πŸ₯³

reduce() is like the ministry of a King. It executes a user-supplied β€œreducer” callback function on each element of the array, passing in return value after calculation and the final result is the single value after running the reducer across all elements of the array.

Syntax πŸ˜‡

This is the syntax for using reduce() using arrow function.

reduce((previousValue, currentValue, currentIndex, array) => { /* ... */ }, initialValue)

Let’s understand the parameters in the syntax

  • callbackFn : Reducer Function which takes in four arguments
    • previousValue: initially this takes the initialValue or value of array[0]. Otherwise, it takes results from the value returned by the callbackFn in the previous call.
    • currentValue : Value of the current element. On the first call, if initialValue is specified then array[0] or else it takes array[1].
    • currentIndex : index position of the currentValue.
    • array: array to traverse
  • initialValue (optional): Value which is to be given to previous on the first call.

Return value :

A new value is returned which results from applying callbackFn over the entire array.

Example Code using reduce() method

const arr=[
    {
        'name':'Aashirwad',
        'roll':4

    },
    {
        'name':'Pankaj',
        'roll':78

    },
    {
        'name':'Ayush',
        'roll':70

    },
    {
        'name':'Nisha',
        'roll':33

    },

]

console.log(arr.reduce((previous,current)=>{
    return previous+current.roll

},0))

//185

Here we display only those elements on the console for which roll > 20. Thus filtering out other values.

Pro Use Case of reduce() πŸ€‘

  • If an operation is to be applied on the entire array to return a particular value it is better to use it instead of defining a new function.

Cons of reduce() πŸ₯²

  • The use case is very particular,i.e specific use case

Gotchas ! 😳

Implementing reduce() from scratch 😎

Reduce takes all the elements in an array and reduces them to a single value. We take in two values previous and current and return after performing an operation over them

So in the below example sum of all roll numbers we pass in a second value alongside callback function to use as the first value of previous.

const arr=[
    {
        'name':'Aashirwad',
        'roll':4

    },
    {
        'name':'Pankaj',
        'roll':78

    },
    {
        'name':'Ayush',
        'roll':70

    },
    {
        'name':'Nisha',
        'roll':33

    },

]

let myreduce = function(arr,callback,initial){
    let acc =initial || 0;

    arr.forEach((e,i)=>{
        acc=callback(acc,arr[i])
    })
    return acc;
}

console.log(myreduce(arr,(previous,current)=>{
    return previous*current.roll

},1))

// 720720

These are some key points to keep my mind while using the four most important methods in JS arrays.🀩

forEach() Method

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

map method

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

filter() method

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

reduce() Method

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

Β