 # Understanding reduce in JavaScript

Let me be honest, it took me a while to understand the Higher-Order Function - `reduce`. In my opinion, I think many faced this situation or facing it. So, let's get started with some theoretical explanation and we hop into some code.

### What is `reduce` ?

• It's a Higher-Order Function
• It takes 2 arguments
• first argument is a function which takes 4 arguments
• second argument is the initial value
• It's one of the methods of Array
• It won't modify the original array

### What does that 4 parameters and intialValue do ?

``````Array.reduce(function (accumulator, value, index, array) {
return /* modified accumulator or just the accumulator */
}, initialValue)
``````

Nice, now what do those parameters do? Okay,

Parameter Description
initialValue The value of the accumulator in the first invocation of the function (1st argument).
Hence the name initialValue.
accumulator This will be the return value of each invocation of the function.
It should be the same type of the initialValue on each and every invocation.
value The value of the array element.
index The index of the array element. (Optional)
array The array itself. (Optional)

### Enough Explaining. Show me the code!

``````// The common example of reduce method
function sum(acc, val) {
// the optional parameters are omitted
return acc + val
}
const arr = [1, 2, 3, 4]
const sumOfArr = arr.reduce(sum, 0) // = 10
// Here the initialValue's type is number
// so the type of `sumOfArr` will be the same (number)
``````

What's happening here? Let's see with this table,

Invocation accumulator value return
First 0 (initialValue) arr = 1 0 + 1 = 1
Second 1 arr = 2 1 + 2 = 3
Third 3 arr = 3 3 + 3 = 6
Fourth 6 arr = 4 6 + 4 = 10

So the result would be the sum of the used array (here `arr`).

``````// The optional parameters are omitted for this ex. too
// and I'm gonna use arrow functions
const rick = ['never', 'gonna', 'give', 'you', 'up', 'never', 'gonna', 'let', 'you', 'down']
const ricksObj = rick.reduce((acc, val) => {
acc[val] = (acc[val] + 1) || 1
return acc
}, {})
// { never: 2, gonna: 2, give: 1, you: 2, up: 1, let: 1, down: 1 }
``````

The ricksObj is a object as initialValue = {}. So here, what the does is super simple. It returns an object with properties of `rick` array elements and values as the occurrence of each element in the array. Let's create a table.

Invocation accumulator value return
First `{}` (initialValue) 'never' acc['never'] is undefined.
So, acc['never'] = 1.
`{ never: 1 }`
Second `{ never: 1 }` 'gonna' Same as above.
`{ never: 1, gonna: 1 }`

On third, fourth and fifth invocation, the array elements are unique so, they all get the value of `1` as per the expression `(acc[val] + 1) || 1`.

Invocation accumulator value return
Sixth `{ never: 1, gonna: 1, give: 1, you: 1, up: 1 }` 'never' As the property never is no more `undefined`, the property's value get incremented.
`{ never: 2, gonna: 1, give: 1, you: 1, up: 1 }`

and so on.

### What else does this method do !?

Let's use an API and use reduce with the response Array.

``````fetch('https://arrowverse-api.vercel.app/api/characters?page=1&limit=10')
.then(res => res.json())
.then(data => {
// ----------------------------------------------------
data = data.reduce((acc, val) => {
if(val.imgUrl !== '') {
acc.push({ name: val.name, imgUrl: val.imgUrl })
return acc
} else {
return acc
}
}, [])
console.log(data)
// -----------------------------------------------------
}
)
``````

There are many properties in the objects inside the array but I need only the name of the character and the image URL, but some characters don't have the image URL, so I need to exclude them. The exact same result is acquired when you use `map` and `filter`, like this

``````fetch('https://arrowverse-api.vercel.app/api/characters?page=1&limit=10')
.then(res => res.json())
.then(data => {
// ----------------------------------------------------
data = data
.map(val => ({
name: val.name,
imgUrl: val.imgUrl
}))
.filter(data => data.imgUrl !== '')
console.log(data)
// -----------------------------------------------------
}
)
``````

So both of them work. I personally like to use `reduce` as it's so compact and powerful. Try the blocks of code in the browser console 