Quick Review (of some) JS Iterator Methods
Tags: javascript, beginners
Published: 2022-09-15 19:45:18

# Reviewing .map(), .find(), .filter(), .reduce() and .forEach()

---

## Introduction

Today I'll be reviewing some JS iterator methods in an attempt to have a better grasp on the concepts. I'll be going over .map(), .filter(), .find(), .reduce() and forEach(). 

Below is a quick summary table:

| Syntax      | Description |
| ----------- | ----------- |
| array.map(callbackFunction)      | Creates a new array made with elements that have been mutated by a function      |
| array.find(callbackFunction)      | Returns the ***first*** element in the array that satisfies the provided test function    |
| array.filter(callbackFunction)   | Returns ***all*** of the elements in an array that satisfies the provided test function       |
| array.reduce(callbackFunction, initialValue)   | Walks through every element in an array, passing it to a function, then adds that result to the previous result. Initial value optional.    |
| array.forEach(callbackFunction)      | Changes original array made with elements that have been mutated by a function      |

---

## .map() Method

.map() executes a function over each element in an array, then returns us a new array.

For example:

Lets say we have an array with a set of 4 numbers.

```
const array1 = [1, 3, 5, 7]
```

And a function that takes a number and multiplies it by 2.

```
function multiplier(e){
   return e * 2
}
```

If we invoke the .map() method on the array using the *multiplier* function, then each element in the array will be passed into that function. Essentially, every element will be multiplied by 2.

```
const array1 = [1, 3, 5, 7]

function multiplier(e){
   return e * 2
}

const newArray = array1.map(multiplier)

console.log(array1)
console.log(newArray)
==> Expected output: [1, 3, 5, 7]
==> Expected output: [2, 6, 10, 14]
```

Take note that the original array was **not** changed.

## .find() Method

.find() returns the *first* element in an array that satisfies the test function's conditions, read from left to right. 

For example:

Lets say we have an array of words, with varying word lengths.

```
const array1 = ["blast", "past", "ghast", "last", "mast", "make"]
```

Then lets have a test callback function that returns a word that is greater than 4 letters long.

```
function findArr(e){
  return 4 < e.length ;
}
```

Using the .find() method, we can find all words in the array that have a word length greater than 4. In this case, it should be either *blast* or *ghast*. However, since .find() only looks for the very first element that satisfies the condition, it should only return *blast*.

```
const array1 = ["blast", "past", "ghast", "last", "mast", "make"]

function findArr(e){
  return 4 < e.length ;
}

const find = array1.find(findArr)

console.log(find)
==> Expected output: "blast"
```

As expected, since only *blast* and *ghast* have greater than 4 letter lengths and *blast* is the very first word in the array that satisfies this condition, it returns *blast* only. 

## .filter() Method

.filter() returns all the elements in an array that satisfies the test function. Unlike .find(), it finds all elements in the array that satisfy this condition and returns a new array. 

Lets take our last example from .find() and use .filter() instead.

Using the .filter() method, we can find all words in the array that have a word length greater than 4. In this case, it should be *blast* and *ghast*.

```
const array1 = ["blast", "past", "ghast", "last", "mast", "make"]

function filterArr(e){
  return 4 < e.length ;
}

const filter = array1.filter(filterArr)

console.log(filter)
==> Expected output: ["blast", "ghast"]
```

Since only *blast* and *ghast* have greater than 4 letter lengths, they were both returned in a new array with just those two words.

## .reduce() Method

.reduce() is a iterator method used to summarize an array into a single value. You pass a callback function into .reduce() and you have the additional option of passing in an initial value. 

The callback function is passed two arguments: the previous value returned from the loop and the next value in the array. If there was an initial value given, it will use that as its first "previous value" in the calculation.

If there is no initial value, it takes index #0 of the array as the initial value instead. See below for clarification.

For example:

Lets take our array from our .map() example as well as an initial value of 2.

```
const array1 = [1, 3, 5, 7]

const initialValue = 2
```

And now lets make our reducer function multiply the previous value, with the current element in the array.

```
function reducer(previousValue, currentElement){
   return previousValue * currentElement
}
```

Using the .reduce() method, we're going to see it calculate:

```
Previous Value * Current Element
```

Through every element in the array, starting with the initial value.

```
const array1 = [1, 3, 5, 7];

const initialValue = 2;

const finalValue = array1.reduce(reducer, initialValue);

function reducer(previousValue, currentElement){
  return previousValue * currentElement
}

console.log(finalValue)
=> Expected output: 210
```

The calculation written out:

```
2 (initial value) * 1 (array1[0]) = 2

2 (previous value) * 3 (array1[1]) = 6

6 (previous value) * 5 (array1[2]) = 30

30 (previous value) * 7 (array1[3]) = 210
```

Now lets take the same example but forego passing in an initial value. This time it takes the value at array1's index #0 and uses that as its initial value.

```
const array1 = [1, 3, 5, 7];

const finalValue = array1.reduce(reducer);

function reducer(previousValue, currentElement){
  return previousValue * currentElement
}

console.log(finalValue)
=> Expected output: 105
```

The calculation written out:

```
1 (array1[0]) * 3 (array1[1]) = 3

3 (previous value) * 5 (array1[2]) = 15

15 (previous value) * 7 (array1[3]) = 105
```

.reduce() is a great iterator for distilling arrays down into a single value by applying a function.

## .forEach() Method

.forEach() works very similarly to .map() in that it takes a function then applies to to every element in the array. **However!** An important distinction is that it does **not** return a new array. In fact, it does not return anything.

Lets take the first example and try doing .forEach() instead of .map():

```
const array1 = [1, 3, 5, 7]

function multiplier(e){
   return e * 2
}

const newArray = array1.forEach(multiplier)

console.log(array1)
console.log(newArray)
==> Expected output: [1, 3, 5, 7]
==> Expected output: undefined
```

You'll notice now that the code returns undefined for *newArray* instead of an array. That is because the .forEach() method does not return data.

If you add a console.log() in the function itself, you'll notice that the individual elements in the array are still being operated on.

```
const array1 = [1, 3, 5, 7]

function multiplier(e){
   return console.log(e * 2)
}

array1.forEach(multiplier)

console.log(array1)
==> Expected output: 2
==> Expected output: 6
==> Expected output: 10
==> Expected output: 14
==> Expected output: [1, 3, 5, 7]
```

.forEach() is typically used in cases where you cannot use any other iterator methods for your specific purposes. It is very similar to other JS for/while loops. 

## Notes

Please let me know in the comments if I've made any errors; I am still very new to coding in JS and these are notes to try to help me understand the concepts better.

## Credits

[MDN .map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
[MDN .find()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
[MDN .filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
[MDN .reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
[MDN .forEach()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)