Understanding Map, Filter and ForEach in JavaScript
Tags: javascript, webdev, programming
Published: 2023-05-18 04:44:03

Ever Happened that you want to do some operations on an array by looping through it and don't know which built-in function you should use so you just google your problem or use Chat-GPT these days and just paste whatever function that comes up or at the end of the day maybe just write a for loop yourself.

Now maybe writing for loop can be comforting because you never fully understood why and when of these built-in functions. So in this blog I'll try to make you understand everything that I understand about these functions.

Lets start with Map

## Map

So Map is a in-built function in JavaScript which is used to iterate/loop over a predefined array and transform its elements and return a new array, so that it doesn't mutates or make any changes in the original array in the process. 

1. It takes a callback function which contains the logic to add elements to our new array. 

2. Now inside the callback function, you write the logic that defines what will be returned to the new array.

3. The value is returned from the callback function and then appended in the new array at the position of the element which is being iterated.

4. Once the iteration is ended , map will return the new array.

5. The New array that Map returns will always be the exact same length of the original array. 

6. Its application is to change or transform the values of the original array. 

Now when I say that it is used to change or transform the values of the original array it doesn't mean that the returned array have to be anything like the original array, You can even return an array where each element is just value 1.

Sounds silly right? But that's what Map does the, new array is just meant to be as same length of the original array, the content is selected by you for each element's position which is being iterated.

For example lets say we have an array like this

```
let fruits = ['apple', 'banana', 'apple', 'watermelon', 'apple']

```

Now I want to make an array where the 'apples' are represented by 1 and all other fruits are represented by 0.

lets see how we can do this

So lets see the basic syntax of a map first

```
array.map(callback(CurrentValue, index));

```

lets break it down
So we started the statement with array on which we need to do the processing then we passed a callback function in the map function now this callback function have 3 parameters

1. CurrentValue - It is the value from our original array which is sent into the callback function with each iteration. Just how we use for loop where we iterate over each element of the loop like this fruits[i] so here you directly get that value which you used to get using fruits[i].

2. Index - Now its pretty much self explanatory, its the index of the current element on which processing will be done. Its an optional Parameter.

Now back to our problem

So now that we understood the syntax lets see how we will get our desired array.

So you remember that it depends upon us what we want to send in the new array at the position of the element which is being iterated.

So in this problem what we can do is in the callback function, where we return the value, we can write an if condition which says that if the CurrentValue is equal to apple return 1 else 0.

```
let fruits = ['apple', 'banana', 'apple', 'watermelon', 'apple']

let new_fruits = fruits.map((elem)=>{
    if(elem === 'apple'){
        return 1
    }
    else{
        return 0
    }
})

console.log(new_fruits) //[ 1, 0, 1, 0, 1 ]
```

Pretty simple right? We just return a new array using our logic.
Our Map function collected the values at each iteration and assigned it to the corresponding position in the new array.

Now we understand that map puts the value in the new array depending on what we return right? What if I dont return anything for a condition?

Like in our above example if I dont return anything if the element is 'apple'

```
let fruits = ['apple', 'banana', 'apple', 'watermelon', 'apple']

let new_fruits = fruits.map((elem)=>{
    if(elem !== 'apple'){
        return 0
    }
})

console.log(new_fruits) //[ undefined, 0, undefined, 0, undefined ]
```
Well as you can see that it returns undefined, but why so? In JavaScript, if a function does not have an explicit return statement or if the return statement is empty, the function implicitly returns undefined. 

When you didn't returned anything from the callback function passed to map, each iteration of the map function still executes the callback for every element of the array. However, since there is no value explicitly returned, the default behavior of the function is to implicitly return undefined.

Lets see one more example before we move to Filter

Suppose I have an object of students which contains students names and IDs now I want to make an array which contains only names of the students.
Well I think its pretty easy to do it, now that we know how map works.

```
const students = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
  { id: 3, name: "Charlie" }
];

const studentNames = students.map(function(student) {
  return student.name;
});

console.log(studentNames);  // Output: ["Alice", "Bob", "Charlie"]
```
There is no need of any condition in this case as we just want to return the name from every object.

Why is it good to use Map?

1. Well allows you to write concise and declarative code. It removes the need for manual iteration using loops like for or while.

2. As it returns a new array it takes care of immutability so whatever you do to the new array the original array would be unaffected.

3. Can be used to create a shallow copy of an array by returning a new array.

Pretty useful right? Lets move on to Filter now

## Filter

So Filter function also iterates over an array and returns a new array, then what makes it different from map? Well map can transforms each value of the original array and return the new array to be of same length as of the original array.
Filter doesn't have both of these features. 

As the name suggests it is used to filter out an array. So if you pass an array it will return an array which wont contain some elements that you decide.
Its syntax is same as Map just replace map with filter

Now how does it removes elements? So in the callback function you can write a logic or whatever you wanna do but you can return only boolean value. Which determines that currentValue will be sent to the new array or not. So if you returned true it will be included in the new array otherwise not.

For example if you have an array of odd and even numbers and you want to return an array with only even numbers then:-

```
const Array = [1, 2, 3, 4, 5, 6];

const NewArray = Array.filter((element)=>{
    if(element%2 === 0){
        return true
    }
})

console.log(NewArray) //[ 2, 4, 6 ]
```
As you can see in this code I didn't specified any return value if the element is odd and still there is no problem, this is because filter function takes it as false by default if boolean value is not specified.

Now we know that filter's callback function only returns Boolean values but I was curios that what will happen if in the above example I returned lets say 5 when the number is even.

And the result was same I got the array with even numbers, But why? Filter's callback function were supposed to return only Boolean values right? So yeah its still returning Boolean Value.

**How?**
So there's something called `truthy` and `falsy` values in JavaScript.

In JavaScript, truthy values are values that are considered "true" when evaluated in a boolean context. They are non-boolean values that are treated as if they were true.

There are many truthy values in JavaScript like Non-empty strings,Numbers,Arrays,Objects,Non-null values,Non-Undefined values etc.

There are simple examples of truthy values too like 

```
if ("Hello") {
  console.log("This will be executed.");
}
```

Here Hello is a non empty string so its a truth value hence true and hence the condition is true.

Now it's recommended that you use Filter only when you want to get a new array with filtered elements, if you just loop through it , it will be unnecessary iterations and will cause problems when the array is large, it not only causes problems but it is also misleading because if you use filter to just iterate others will be confused looking at your code.

And this wraps up the concept of Filter.

## ForEach

So this loop is simple compared to Map and Filter as it doesn't provide any exclusive feature like them. It doesn't return any new array which is a transformed or Filtered version of the original array , basically it doesn't return any thing. Its basically a concise way to write a for loop, it doesn't do anything different from a simple for loop. Just like you create a new array out of the the for loop scope and then push new elements in the array while the loop runs, same you do in Foreach loop. 

There is one difference between a for loop and ForEach loop is that, that you can't stop a ForEach loop like you do with For Loop, you can't add a `break` statement to end the loop. And that's same for all the three fucntions that we talked about. It will no doubt loop through every element.

Here is a simple problem which is solved using for loop and then with ForEach.

**Using For loop**

```
var numbers = [1, 2, 3, 4, 5];
var sum = 0;

for (var i = 0; i < numbers.length; i++) {
  sum += numbers[i];
}

console.log(sum); // Output: 15
```

**Using Foreach Loop**

```
var numbers = [1, 2, 3, 4, 5];
var sum = 0;

numbers.forEach(function(number) {
  sum += number;
});

console.log(sum); // Output: 15
```

This Wraps up all of the three functions , hope you understand them well now 😁