Array.prototype.reduce()
The reduce()
method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.
Syntax
array.reduce( (accumulator, currentValue, currentIndex, sourceArray) => {}, initialValue )
accumulator
- accumulates the callback's return value. It is the accumulated value previously returned in the last invocation of the callback, orinitialValue
, if supplied.currentValue
- the current element being processed in the array.index
- the index of the current element being proccessed in the array. Starts from index 0 if aninitialValue
is provided. Otherwise, starts from index 1.array
- the arrayreduce()
was called upon.initialValue
- a value to use as the first argument to the first call of the callback. If noinitialValue
is supplied, the first element in the array will be used and skipped.
index
, array
and initialValue
- are optional.
Basic Examples
const sum = [4, 5, 32, 24, 8].reduce((acc, curNum)=>acc+curNum);
// 4 + 5 + 32 + 24 + 8
console.log(sum); // expected output: 73
reduce
method
Common uses of Changing the data structure:
const subjects = [
{ id: 1, name: 'Math', content: 'All about numbers and calculations' },
{ id: 2, name: 'Chemistry', content: 'All about matter, its properties and substances' },
{ id: 3, name: 'Physical training', content: 'All about fitness exersises' }
]
const subjectsObj = subjects.reduce((acc, sub)=>{
const { id, ...rest } = sub;
return { ...acc, [id]: rest }
}, {});
console.log(subjectsObj);
/* expected output:
1: { name: "Math", content: "All about numbers and calculations" }
2: { name: "Chemistry", content: "All about matter, its properties and substances" }
3: { name: "Physical training", content: "All about fitness exersises" }
*/
A vanilla JS equivalent of lodash's groupBy() method
const colorGroups = [
{ color: "Orchid ", group: "Purple" },
{ color: "Teal", group: "Green" },
{ color: "Salmon", group: "Red" },
{ color: "Fuchsia", group: "Purple" },
{ color: "Indigo", group: "Purple" },
{ color: "Crimson ", group: "Red" },
{ color: "Lime", group: "Green" },
{ color: 'OliveDrab', group: 'Green' }
];
function groupBy(arr, property) {
return arr.reduce( (groupObj, colorObj) => {
let key = colorObj[property];
if(!(key in groupObj)) groupObj[key] = [];
groupObj[key].push(colorObj);
return groupObj;
}, {});
}
console.log(groupBy(colorGroups, 'group'));
/*
expected output:
{
Purple: [ {color: "Teal", group: "Green"}, {color: "Lime", group: "Green"}, {color: "OliveDrab", group: "Green"} ],
Green: [ {color: "Orchid ", group: "Purple"}, {color: "Fuchsia", group: "Purple"}, {color: "Indigo", group: "Purple"} ],
Red: [ {color: "Salmon", group: "Red"}, {color: "Crimson ", group: "Red"} ]
}
*/
Counting of values
const cars = ['Nissan', 'Renault', 'Ford', 'Honda', 'Ford', 'Toyota', 'Nissan', 'Ford'];
let carsAmount = cars.reduce((carsObj, car) => {
if (car in carsObj) {
carsObj[car]++;
} else {
carsObj[car] = 1;
}
return carsObj;
}, {});
console.log('carsAmount', carsAmount); // expected output: { Nissan: 2, Renault: 1, Ford: 3, Honda: 1, Toyota: 1 }
Collect input values from a form:
<form>
<input type="text" name="firstname" placeholder="Enter first name" value="JS"/><br/>
<input type="text" name="lastname" placeholder="Enter last name" value="help"><br/>
<input type="email" name="email" placeholder="Enter e-mail" value="help@js.help"/><br/>
<button type="submit">Submit</button>
</form>
let formEl = document.querySelector('form');
formEl.addEventListener('submit', e => {
const inputElsArr = [...e.currentTarget.querySelectorAll('input')];
const formData = inputElsArr.reduce((data, inputEl)=>{
const inputName = inputEl.getAttribute('name');
const inputVal = inputEl.value;
data[inputName] = inputVal
return data;
}, {})
console.log('formData', formData); // expected output: {firstname: 'JS', lastname: 'help', email: 'help@js.help'}
});
Promise chains
When the order in which the promises should resolve is important
const promiseQueue = (promiseFn, list) =>
list.reduce(
(queue, item) => queue.then(async result => {
const itemResult = await promiseFn(item);
return result.push(itemResult);
}),
Promise.resolve([])
);
List of methods and techniques which were used in the examples above and you may be curious to learn more about them:
- addEventListener - adds a listener to the list of callbacks called when the specified event is fired.
- querySelector - returns the first element that matches the specified selector.
- querySelectorAll - returns a static NodeList repesending a list of elements that match the specified group of selectors.
- getAttribute - returns the value of a specified attribute on the element.
- in - returns true if the specifed property is in the speicified object.
- async - an
async
function always returns a Promise. - destructuring
List of Resources
MDN: Array.prototype.reduce
Medium: Explanation of javascript’s reduce() with a real world use case
ITNEXT: Useful “reduce” use cases