Photo by Blake Connally on Unsplash
JavaScript Array Methods Detailed Review of forEach() ,map , filter() and reduce()
Table of contents
- Letβs first understand π€ What is an Array?
- Which specific Array Methods will we learn about?
- forEach() Method π
- map method π
- filter() method π₯³
- reduce() method π₯³
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 elementelement
: Current element being worked on in array.index
(Optional) : The index of element in arrayarray
(Optional) : Array upon whichforEach()
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 timecallbackFn
is called returned value is added to thenewArray
element
: Current element being worked on in array.index
(optional): The index of element in arrayarray
(optional): Array upon whichmap
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 eachelement
of the array and return a value that is eithertrue
to keep the element innewArray
orfalse
to not keep the element in thenewArray
.element
: Current element being worked on in array.index
(optional) : The index of element in arrayarray
(optional) : Array upon whichfilter()
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 argumentspreviousValue
: initially this takes theinitialValue
or value ofarray[0]
. Otherwise, it takes results from the value returned by thecallbackFn
in the previous call.currentValue
: Value of the current element. On the first call, ifinitialValue
is specified thenarray[0]
or else it takesarray[1]
.currentIndex
: index position of thecurrentValue.
- 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.π€©
Additional links
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