Unlock the Power of JavaScript’s reduce: 5 Creative Uses Beyond Simple Summing
This tutorial explores why the .reduce() method feels intimidating, demonstrates its basic usage with addition and multiplication, and then showcases five unconventional applications—including converting arrays to objects, flattening nested arrays, performing dual calculations in a single pass, merging map and filter, and sequencing asynchronous calls—while providing clear code examples and performance considerations.
Why .reduce() can feel complex
.reduce()is often introduced after .map() and .filter(), so developers are less familiar with its signature. The reducer receives an accumulator (the value returned from the previous call) and the current array element . Because the accumulator can be any type—number, string, object, or even another array—the mental model is less straightforward than the fixed‑type operations of .map() and .filter().
Basic numeric examples
function add(a, b) { return a + b; }
function multiply(a, b) { return a * b; }
const sampleArray = [1, 2, 3, 4];
const sum = sampleArray.reduce(add, 0); // 10
const product = sampleArray.reduce(multiply, 1); // 24
console.log('sum =', sum);
console.log('product =', product);These examples show how .reduce() can replace simple loops. The real power appears when the accumulator is a different type from the array elements.
Common patterns using .reduce()
Convert an array to an object (lookup table)
function keyByUsername(acc, person) {
return { ...acc, [person.username]: person };
}
const peopleArr = [
{ username: 'glestrade', displayname: 'Inspector Lestrade', email: '[email protected]', lastSeen: '2019-05-13T11:07:22+00:00' },
{ username: 'mholmes', displayname: 'Mycroft Holmes', email: '[email protected]', lastSeen: '2019-05-10T11:21:36+00:00' },
{ username: 'iadler', displayname: 'Irene Adler', email: null, lastSeen: '2019-05-17T11:12:12+00:00' }
];
const peopleObj = peopleArr.reduce(keyByUsername, {});
console.log(peopleObj);The resulting object can be used for fast look‑ups by username .
Expand a small array into a larger one
const fileLines = [
'Inspector Algar,Inspector Bardle,Mr. Barker,Inspector Barton',
'Inspector Baynes,Inspector Bradstreet,Inspector Sam Brown',
'Monsieur Dubugue,Birdy Edwards,Inspector Forbes,Inspector Forrester',
'Inspector Gregory,Inspector Tobias Gregson,Inspector Hill',
'Inspector Stanley Hopkins,Inspector Athelney Jones'
];
function splitLine(acc, line) {
return acc.concat(line.split(/,/g));
}
const investigators = fileLines.reduce(splitLine, []);
console.log(investigators);This turns a list of comma‑separated strings into a flat array of names.
Perform two calculations in a single traversal
const readings = [0.3, 1.2, 3.4, 0.2, 3.2, 5.5, 0.4];
function minMaxReducer(acc, reading) {
return {
minReading: Math.min(acc.minReading, reading),
maxReading: Math.max(acc.maxReading, reading)
};
}
const init = { minReading: Number.MAX_VALUE, maxReading: Number.MIN_VALUE };
const result = readings.reduce(minMaxReducer, init);
console.log(result); // { minReading: 0.2, maxReading: 5.5 }The accumulator is an object that tracks both the minimum and maximum values, avoiding a second pass.
Combine .map() and .filter() into one pass
function notEmptyEmail(x) {
return x.email !== null && x.email !== undefined;
}
function getLastSeen(x) { return x.lastSeen; }
function greater(a, b) { return a > b ? a : b; }
const mostRecent = peopleArr
.filter(notEmptyEmail) // keep only users with email
.map(getLastSeen) // extract the date string
.reduce(greater, ''); // find the latest date
console.log(mostRecent);For large data sets the three steps can be merged into a single reducer to avoid intermediate arrays.
Run asynchronous functions sequentially
async function fetchMessages(username) {
return fetch(`https://example.com/api/messages/${username}`).then(r => r.json());
}
async function chain(promise, username) {
const acc = await promise; // previous result object
const data = await fetchMessages(username);
return { ...acc, [username]: data }; // add new entry
}
const msgObj = peopleArr
.map(p => p.username)
.reduce(chain, Promise.resolve({}));
msgObj.then(console.log);The reducer chains promises so each API call finishes before the next one starts, which is useful for rate‑limited endpoints.
Why .reduce() is less frequently seen
Because .reduce() can produce any shape of result, it is often considered harder to read than the more explicit .map(), .filter() or .flatMap(). When readability is the primary concern, developers prefer the latter. However, mastering .reduce() enables patterns that reduce the number of passes over data and can improve performance in memory‑constrained scenarios.
Original source: https://jrsinclair.com/articles/2019/functional-js-do-more-with-reduce/
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
