question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

no-param-reassign - Array.prototype.reduce and alike exceptions

See original GitHub issue

Hi and thanks everybody who participated on no-param-reassign! I know, this is a duplicate of #8007 and #6339. This is a lobby.

Summary

no-param-reassign is pretty useful rule. I’m not breaking this rule all time except if I write code using this perfect function: Array.prototype.reduce(function(accumulator, currentValue) => accumulator, initialAccumulator )

Currently there is no way to hint no-param-reassign rule to relax reduce function accumulator in perfectly finest way.

tl;dr

I really ❤️ no-param-reassign rule. But there is at least one edge case where assigning to passed variable is perfectly fine, possibly the best way to write it down — someArray.reduce() function. I’m sure that everyone knows this function, using it time to time for transforming data from one shape to another.

I see misunderstanding of reduce with no-param-reassign rule leading to wasting a lot of resources. It is so simple. Just use spread operator for copying result of previous iteration:

// this code is perfectly fine, but violates rule:
const firstNameCount = users.reduce((firstNameCount, user) => {
  firstNameCount[user.firstName] = (firstNameCount[user.firstName] || 0) + 1;
  return firstNameCount;
}, {});

// this code is performing poorly, wasting memory and CPU, but fits rule :-(
const firstNameCount = users.reduce((acc, user) => {
  const result = { ...acc };
  result[user.firstName] = (acc[user.firstName] || 0) + 1;
  return result;
}, {});

This use case is so special and simple that there is no need for more similar functions. This is the pattern in fact. A coding primitive, so special that famous framework Redux is mostly about thinking about this one function, deriving all the possibilities from using this pattern!

If you need more…

This is so special case that it can have it’s own syntax, but, you know, this is not needed in javascript. But I can imagine language expression construct like this:

reduce <Iterable> into <lvalue> [ = <rvalue> ] with <identifier> [, <identifier>] as <statement using <lvalue> >

To be more concrete:

const firstNameCount = users.reduce((firstNameCount, user) => {
  firstNameCount[user.firstName] = (firstNameCount[user.firstName] || 0) + 1;
  return firstNameCount;
}, {});

can be written like this:

const firstNameCount =  reduce users into firstNameCount = {} with user as {
  firstNameCount[user.firstName] = (firstNameCount[user.firstName] || 0) + 1;
}

const firstNameCount = reduce users into firstNameCount = {} with user [, index] as {   firstNameCount[user.firstName] = (firstNameCount[user.firstName] || 0) + 1; }

PS: This is only illustrative example of language construct! I cannot imagine language except Pascal which want introduce this… 😄

Is Array.prototype.reduce only exception?

I thing no. But I percept it as language primitive so it should be only default exception.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
ilyavolodincommented, May 13, 2017

This would also apply to reduceRight, however the problem with creating such enhancement is that we don’t know if you are calling reduce on the array, or on your custom made object. We don’t track variable types in ESLint, so we don’t really have a good way to figure out if the current reduce function should be excluded or not.

0reactions
daaaincommented, Nov 30, 2017

For anyone who is just looking for the quick solution, this is how you disable the warning:

const firstNameCount = users.reduce((firstNameCount, user) => {
  firstNameCount[user.firstName] = (firstNameCount[user.firstName] || 0) + 1; // eslint-disable-line no-param-reassign
  return firstNameCount;
}, {});
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to handle eslint no-param-reassign rule in Array ...
I just wrap the reduce functions in a lint rule disable block, ie: /* eslint-disable no-param-reassign */ const newObject = ['a', 'b', 'c'].reduce((result, ......
Read more >
no-param-reassign - ESLint - Pluggable JavaScript Linter
A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. Maintain your code quality with ease.
Read more >
TypeError: Reduce of empty array with no initial value
The JavaScript exception "reduce of empty array with no initial value" occurs when a reduce function is used.
Read more >
eslint-plugin-no-param-reassign-allow-reduce - npm
A copy of the 'no-param-reassign' rule but with allowances made for array.reduce(). Latest version: 1.0.2, last published: 7 months ago.
Read more >
TypeError: Reduce of empty array with no initial value
The JavaScript exception "reduce of empty array with no initial value" occurs when ... Array.prototype.reduce.call(names, (acc, name) => acc + ", " +...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found