The
reduce()
method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value. MDN
use the reduce function on javascript arrays to transform a list of values into something else.
You need two things for .reduce()
A reducer function takes an accumulator and return a new accumulator, by running every item in the array against the accumulator.
.reduce()
always returns the final value of the accumulator. Remember, reducer function returns the accumulator. (i.e. Use the return
in your functions)
In other words, the reducer function fires once for every item in the array and keeps accumulating the value to give a new value.
Here’s an example:
1const data = [3, 98, 16, 36, 13, 22, 46]
2
3let reducer = (accumulator, item) => accumulator + item
4
5let initialValue = 0
6
7let total = data.reduce(reducer, initialValue)
8
9console.info('total:', total) // total: 234
In the example above, we reduced an array to a final value (final accumulator), by adding the numbers in the data
array, one by one to the accumulating value.
We started with an initial value (0), added it to the accumulator (3, first item of the data array) to get a new accumulator (0+3 = 3), then got to the next value (98), added that to the previous accumulator (3) to get a new accumulator (98+3 = 101), then got to the next value (16), added that to the previous accumulator (now 101) to get a new accumulator (16+101 = 117) and so on… till all items in the array were done and we ended with a final accumulator value of 234.
1let votes = [
2 'angular',
3 'angular',
4 'react',
5 'ember',
6 'react',
7 'react',
8 'vanilla'
9]
10
11let initialValue = {}
12
13let reducer = (tally, vote) => { // tally is initialValue, vote is first item in votes array
14 if (!tally[vote]) { // if a key value doesn't exist
15 tally[vote] = 1
16 } else {
17 tally[vote] = tally[vote] + 1 // if a key value exists, increment it
18 }
19 return tally
20}
21
22let result = votes.reduce(reducer, initialValue)
23console.info(result) // { angular: 2, react: 3, ember: 1, vanilla: 1 }
.map()
is a reducer function. So is .filter()
. And they can be easily chained to create complex functions. But using [^footnote] Here’s an example of the time difference between using map+filter vs. reducereduce()
can be faster than mapping and filtering when you have a lot of data.
We’re going to get an array containing a million items, get all the even numbers in it, multiply them by two and get the resulting array.
1let bigData = []
2for (let i = 0; i < 1000000; i++) {
3 bigData[i] = i // get an array containing a million numbers
4}
1console.time('bigData')
2
3let filterMappedData = bigData.filter(val => {
4 val % 2 === 0
5 }).map(val => val*2)
6
7console.timeEnd('bigData') // bigData: 44.423ms
1console.time('bigDataReduced')
2
3let reducedData = bigData.reduce((acc, val) => {
4 if (val % 2 === 0) {
5 acc.push(val *2)
6 }
7 return acc
8}, [])
9
10console.timeEnd('bigDataReduced') // bigDataReduced: 68.954ms
i ran the example which accompanied the claim in the video 8 times, and reduce always took longer than map+filter
1~/Sandbox $ node example.js
2bigData: 44.423ms
3bigDataReduced: 68.954ms
4~/Sandbox $ node example.js
5bigData: 44.178ms
6bigDataReduced: 77.308ms
7~/Sandbox $ node example.js
8bigData: 34.717ms
9bigDataReduced: 48.441ms
10~/Sandbox $ node example.js
11bigData: 43.447ms
12bigDataReduced: 61.104ms
13~/Sandbox $ node example.js
14bigData: 37.742ms
15bigDataReduced: 51.461ms
16~/Sandbox $ node example.js
17bigData: 34.192ms
18bigDataReduced: 46.665ms
19~/Sandbox $ node example.js
20bigData: 42.159ms
21bigDataReduced: 46.572ms
22~/Sandbox $ node example.js
23bigData: 31.489ms
24bigDataReduced: 51.182ms
Array.reduce => returns single value Array.map => returns new Array
Loop with memory. You need to provide it a reducer function
Accumulator = previous state = the last value you returned from the reducer function Current = current element in the loop
Start with many things and reduce it down to one thing
https://www.youtube.com/watch?v=tVCYa_bnITg