What is the difference between map, filter and reduce?
All three of them take a function and use it across an array, but they build different results. map gives you back a new array with the same number of items, where every item is the result of the function. filter gives you back a new array that holds only the items the function accepted, so its length can be anything from zero up to the original length. reduce gives you back one single value that you build up as it goes, and that value can be of any type at all.
const orders = [
{ id: 1, total: 120, paid: true },
{ id: 2, total: 80, paid: false },
{ id: 3, total: 200, paid: true }
];
const totals = [];
for (const order of orders) {
totals.push(order.total);
}
console.log(totals); // 120, 80, 200
const paidOrders = orders.filter(function (order) {
return order.paid;
});
console.log(paidOrders.length); // 2
const sum = orders.reduce(function (runningTotal, order) {
return runningTotal + order.total;
}, 0);
console.log(sum); // 400
Two facts make map and filter easy to reason about. They never change the original array, and they always give you a new one. The function they call also receives the value, the position, and the whole array, so you can use the position when you need it.
reduce is the flexible one, and it is also the easiest one to misuse. It takes an accumulator and a function. It calls that function once for every item, and each time it passes in the running result and the current item. The second argument that you give to reduce is the starting value of the accumulator. Leaving it out is a common source of bugs, because the accumulator then starts as the first item, and an empty array throws an error. Passing 0 on purpose for a sum, or an empty object for a grouping, removes that surprise.
The rule of thumb is that you should reach for reduce only when map and filter cannot express what you need. If you can change each item and get the answer you want, use map. If you want a smaller group, use filter. reduce is for the cases where the answer is not a simple change and not a simple subset.