What s wrong with Array.reduce ?
Davide de Paolis
Posted on July 30, 2020
We use XO for our code linting. Recently I upgraded to its latest version and suddenly I had lots of errors as soon as I tried to commit (**).
What was wrong?
Well. It seems that there is a new trend out there.
Array.reduce is the new most hated guy.
It is disliked so much that a new ESLint rule was added to prevent - or reduce its usage.
What the heck!
I remember that when I started using it 3 years ago, it took me some time to understand the use case and find it cool and useful. And now, even though I don´t use it so often, it generally makes the code look quite nice and smart. Until now, I guess.
When I found all these eslint errors I was quite pissed, first because they were unexpected and I did not want to spend time fixing my code, nor cluttering it with eslint-disable
comments to ignore it. But I was also quite intrigued by the reasons behind this opinionated choice from AVA contributors.
I read some of the comments in the thread and started reconsidering the snippets in our repository that contain Array.reduce.
Let´s consider this simplified example, where we have a list of records and we want to validate them and aggregate all the valid and invalid ones.
const isValid = (record) => // run some validation logic over the record props and return true or false
module.exports.analyzeResults = (records = []) => {
return records.reduce(
(acc, current) => {
if (isValid(current)) {
acc.valid.push(current)
} else {
acc.invalid.push(current)
}
return acc
},
{valid: [], invalid: []}
)
}
With Array.reduce we can achieve it quite nicely, with one iteration only over the list and returning 2 new arrays.
What would be the alternative without Array.reduce and using Array.filter and Array.map instead, to still be as functional as possible?
module.exports.analyzeResults = (records = []) => {
const valid = records.filter(r => isValid(r))
const invalid = records.filter(r => !isValid(r))
return {valid, invalid}
}
```
I know already what you are going to say:
> Ehi, but you are iterating over the list twice!!
True.
But the code is undoubtedly simpler and nicer to read.
So to some extent is the same objection many devs still say when it comes to use {% raw %}`
array.map(simplifyDataStructure).filter(bySomeProp).map(extractOnlySomething).filter(whatIwant)`
against doing everything in one single For Loop.
> Readability and Testability of the single operations
So unless you have a very very big dataset, it is really better to favour readability or simplicity rather than stuffing everything in a _complex_ reduced method.
I am not entirely sold on the new trend. And I am not going to rewrite all my methods using Array.reduce, but this discussion really tickled my interest and helped me question my stance and coding.
What do you think?
---
(**)
> ProTip: Use [Husky](https://www.npmjs.com/package/husky) to create a git hook so that whenever you try to commit XO is run and your code is linted. that really helps to enforce coding standards in your team, and prevent unnecessary pickiness during code reviews.
Posted on July 30, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.