About the .reduce Method
Published: 2022-05-31 01:56:05

**Hi, I am Hannah.**

Novice coder learning through writing.

Any constructive input or clarifications welcome :)

## What does .reduce do?

The .reduce method takes in an array and performs a reducer function callback, written by the user, on each element of the array. The final result of the .reduce method is a single value. This value may be an integer, string, object, ect.

The .reduce method is non-destructive to the original array. 

## How to build the .reduce function

### Parameters

1. **Callback function**
This is the reducer function supplied by the user.

2. **Initial Value (optional)**
This is our starting point. 

We can then formulate the basic structure of our .reduce method as shown below:

```
array.reduce( () = > {

}, 0)
```
The arrow function will become the user-supplied **callback function**, and we have set the **initial value** at 0.

## More on the Callback function

The callback function takes 4 parameters.

**Accumulator** - (required)
This is the value that we want to reduce our array to. 
For the code above, we want to find the _total_ fish caught.

**Current Value** - (required)
The element of the array that we are currently looping through. For the array above, we want to loop through each individual fish.

I will be using the following array to demonstrate how the .reduce method works. With this array, I would like to find the total amount of fish caught.

```
let fish= [
  {name: 'Halibut', amount: 100},
  {name: 'Pacific Cod', amount: 10},
  {name: 'Yellow Irish Lord', amount:14},
  {name: 'Rougheye', amount: 22}
]
```
The start to our function will look like this:
```
let totalFish = fish.reduce((total, fish) => {

}, 0)
```

**Current Index** - (optional)
This is the the current index of the current value in the function. 

**Array** - (optional)
This is the array we are iterating through. In the sample above, it would be the fish array.

```
let num1 = fish.reduce((total, fish, index, array) => {
 
}, 0)
```
Typically, when coming across the .reduce function, we will only see the required parameters (accumulator and current value). We will see the optional parameters occassionally, as needed by the developer. 

### Return
This is the value that we want to have returned upon completion of running the reducer function through the entire array.
**You must return something for the .reduce function to work.**

```
let totalFish = fish.reduce((total, fish) => {
  return total + fish.amount
}, 0)
```
## What is happening in our code?

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zb1p0cmpqzl99mm7yjxd.png)

**First Loop** - Our total (i.e. accumulator) equals 0, what we set our initial value to. Our fish amount equals 100.

**Second Loop** - Our total equals 100, which is the sum of our inital value + the previous fish amount. Our fish total equals 10. 

**Third Loop** - Our total equals 110, which is the sum of the second loop total + the previous fish amount. Our fish total equals 14.

**Fourth Loop** - Our total equals 124, which is the sum of the third loop total + the previous fish amount. Our fish amount is 22.

**Final Value** - Our total equals 146, which is the sum of the fourth loop total + the previous fish amount. We have finished our iteration. 

For each iteration, our total becomes what is returned from the previous iteration. 

## More about the initial value

**What happens if we do not set an initial value?****

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ts9zak3qnvcaifn41yy8.png)

Our numbers.reduce method acts as expected. We expect our function to take each number in the array and multiply it by 3 to get a final value of 183.

Our numbers2.reduce method does not act as expected. Because we did not set our initial value, the reduce method sets the total as the value at index[0], 5 in this case, and our number begins at 11 for our first iteration. We do not multiply 5 by 3, so our expected value is 10 less than expected. 

It is important to set an initial value to avoid errors.

## Returning an Object

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ejoh4ncyvnz1lg67f98.png)
Above we have an array with different fish caught, we want to keep a tally of these fish and return it as an object.

**Writing our reducer function**
Our accumulator is our tally, our current value is our fish.
Our if statement is stating, _if_ our current fish is not in our object, we will add the fish to the object with a tally value of 1. 
_Else_, if our current fish is in our object, we will increment the tally by 1. 
We are then returning the tally.
It is very important to remember to **return** the tally for the function to work.

**Calling the reducer function**
We are setting the .reduce method to the variable tallyFish. 
Then, we call the .reduce method on the fish array with the first parameter being our reducer function and our second parameter (initial value) is an empty object.

**Result**
The tally (our accumulator) is updated through every iteration of our array. When we console.log our variable, tallyFish, we see the final result. 

**Above are the basics of the .reduce method in a nutshell.**
The following resources provide more in-depth coverage of this topic, and a very useful video. 
Thanks for reading! 

## Resources
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
https://www.youtube.com/watch?v=s1XVfm5mIuU
https://egghead.io/lessons/javascript-reduce-an-array-into-a-single-object