Reduce( )ππππ: What, Why and How?
Exposition: I am a CSS Grid enthusiast, a Javascript fan, a React-oholic and a passionate Vue-r. I want to further my knowledge in coding by writing about things that confuse me. This is the first post in this series and the character is reduce ( ), the coolest pal in the array built-in method club.
Rising Action: More often than not, if you are looking for commuting a single value from an array, reduce ( ) is your pal π.
The
reduce()
method executes a reducer function (that you provide) on each member of the array resulting in a single output value.The reducer function takes four arguments: 1. Accumulator (acc), 2. Current Value (cur), 3. Current Index (idx), 4. Source Array (src)
The return value of a reduce ( ) is evaluated by repeatedly taking a single element (acc) from the array (src) and combining it with the current value(cur).
The most common use of a reduce( ) function is either to find the sum of all numerical values inside an array:
const total = [ 0, 1, 2, 3 ].reduce(
( accumulator, currentValue ) => accumulator + currentValue,
0
);
// total is 6
or counting the instances of each items inside an array:
const donuts = ["chocolate glazed", "maple dip", "strawberry, "chocolate glazed", ,"maple dip", "chocolate glazed"]
const countedDonuts = donuts.reduce(function (donuts, donut) {
if (donut in donuts) {
donuts[donut]++;
}
else {
donuts[donut]= 1;
}
return donuts;
}, {});
// countedDonuts is:
// { 'chocolate glazed': 3, 'maple dip': 2, 'strawberry': 1 }
Climax: However, there are so much more we can do πͺπ»! Here are some great usages:
- Organize data: say you have an array of data like this and you would like to have it organize by the name of the customers.
const input = [['Julia Smith', 'Jade Plant', '2', '10'],['Julie Smith', 'Aloe Vera', '1', '20'],['Julia Smith', 'Snake Plant', '2', '50'],['Tom Jones', 'Jade Plant', '5', '10'],['Tom Jones', 'Aloe Vera', '2', '20'],['Tom Jones', 'Ball Cactus', '1', '35']];
Letβs organize the data for each customer:
const output = input.reduce((customers, line) => {customers[line[0]] = customers[line[0]] || [];customers[line[0]].push({name: line[1],price: line[2],quantity: line[3]})return customers;}, {})console.log(JSON.stringify(output, null, 2));
Keep in mind, when the parser goes through the code, each line is the individual item inside the array. We use the bracket notation here to get the name of the customer with:
customers[line[0]]
We start with an empty one and push the name, price and quantity as keys to that empty object as set out as initial value in the reduce function. Our output looks like this:
"Julia Smith": [
{
"name": "Jade Plant",
"price": "2",
"quantity": "10"
},
{
"name": "Snake Plant",
"price": "2",
"quantity": "50"
}
],
"Julie Smith": [
{
"name": "Aloe Vera",
"price": "1",
"quantity": "20"
}
],
"Tom Jones": [
{
"name": "Jade Plant",
"price": "5",
"quantity": "10"
},
{
"name": "Aloe Vera",
"price": "2",
"quantity": "20"
},
{
"name": "Ball Cactus",
"price": "1",
"quantity": "35"
}
]
}
2. Chain Promises: we can also use reduce to run promises in a chained matter (in other words, asynchronously).
const promiseArray = ['promise1', 'promise2', 'promise3', 'promise4'];promiseArray.reduce((promiseChain, currentPromise) => {return promiseChain.then(() => {console.log(currentPromise);return new Promise(res => setTimeout(res, 1000));});}, Promise.resolve()).then(() => console.log('done'));// will log promise1, promise2, promise3, promise4, 'done' in 1s intervals
In this example, we are calling .reduce( ) on the list of promises (just strings for demo purpose) with an initial value of Promise. resolve( ). The interpreter will then go through each promise and resolve them one by one. Every time one promise gets resolved, it will add a .then( ) to the initial value.
Falling Action: Before you run to refractor your code with reduce and taste it sweet sweet power, let me bore you with couple important lessons I (for sure) and other folks have learnt. You can thank me or Peleke (link to original post) later.
- always return.
- always set an initial value.
- remember reduce( ) returns a single value.
Resolution: For the longest time, I was intimidated by reduce. Whenever I see it in a solution of a stack overflow post, I would freeze and try to look for another solution. But now, I am glad that we are pals now.
Credits: This is a topic that has been well talked about inside the community. For the creation of this post, I was inspired by the following resources:
- MDN web docs
- Summarizing with Reduce, Eloquent Javascript
- How JavaScriptβs Reduce method works, when to use it, and some of the cool things it can do
- How JavaScriptβs Array Reduce Works β #JavaScript30 18/30
- Reduce basics β Part 3 of Functional Programming in JavaScript
- Reduce Advanced β Part 4 of Functional Programming in JavaScript
- Reduce an array to chained promises
- How to Use Map, Filter, & Reduce in JavaScript
Here are some other places you can find me on the Internet:
I coded a website for myself.
I write at-the-moment short blog post (people also call them tweets): https://twitter.com/ChaoyueZ
Wanted to know about my career journey? Head over: https://www.linkedin.com/in/chaoyuezhao/
And of course, you want to know what food I eat: https://www.instagram.com/chaoyue_zhao/?hl=en