DEV Community

Discussion on: What s wrong with Array.reduce ?

Collapse
 
zapbampow profile image
Clayton Ingalls

A number of people have mentioned "good" and "bad" uses of reduce. I'd love an example of what a good and a bad use would be.

I love reduce. My coworkers don't. I've always assumed the difference is a matter of familiarity with it. But I recognize that some of my code using reduce has been a pain point to some of my coworkers. So I'm working to use other solutions, even when I would personally prefer to use it.

As a simplified example, we might use these different solutions which use about the same amount of code and only loop once.

const original = [
    { a:1, b:2, c:3 },
    { a:4, b:5, c:6 }
]

// Solution needs to return [ { a: 1, b: 2 }, { a: 4, b: 5 } ]

const loveReduce = original.reduce((acc, cur) => {
    const obj = {
        a: cur.a,
        b: cur.b
    };
    acc.push(obj)
    return acc;
}, [])

let notReduce = [];
original.forEach(item => {
    const obj = {
        a: item.a,
        b: item.b
    };
    notReduce.push(obj);
});
Enter fullscreen mode Exit fullscreen mode
Collapse
 
vonheikemen profile image
Heiker

I can talk about the "good use case" a little bit.

Let's start with the classic, adding numbers.

const array = [1, 2, 3, 4];
const add = (one, another) => one + another;

array.reduce(add);
// => 10

There is a pattern here that is useful. If you squint your eyes you'll see that we have an array with a single data type (Number) and we have binary operation that works with that data type (add).

That simple pattern can be applied to more complex data types. Let's make an example with nested arrays.

const array = [
  ['hello'],
  ['awesome', 'hello'],
  ['!!', 'world'],
  ['!!']
];

const intersection = (one, another) => {
  const set = new Set([...one, ...another]);
  return Array.from(set);
};

array.reduce(intersection);
// => [ "hello", "awesome", "!!", "world" ]

In here we create a new array with the unique elements of each array.

Notice how in the functions add and intersection don't mention anything about an accumulator or a currentValue? That's the power of reduce. I guess you can say that it can "increase the capacity" of a binary operation. This in my opinion is the best use of reduce.

Now, don't take these example to the letter, I'm not trying to say these exact situations are a good use of reduce. I'm trying to show a pattern where reduce can shine.

I talk about this in more detail in this article.

Collapse
 
avalander profile image
Avalander

This seems a prime candidate for map though.

const result = original.map(({ a, b }) => ({ a, b }))
Enter fullscreen mode Exit fullscreen mode