Skip to content
Advertisement

Passing _.groupBy to _.partialRight seems to give incorrect results

Here’s a JavaScript object,

JavaScript

and here’s a code that correctly groups the items by .id in each of the two arrays ojb.a and obj.b,

JavaScript

the result being

JavaScript

The lambda, however, is in fact just the partial application of _.groupBy to its second argument, which is set to 'id', so I thought something like this should work,

JavaScript

or at least something like this

JavaScript

however, neither of them works, both resulting in this object:

JavaScript

Why is that? Is it a bug in lodash? Or is it because of how JavaScript works? In the latter case, what’s happening?


I’ve found an existing question + self-answer which gives a solution for making the code above work:

JavaScript

However part of my question is still not answerd: why do I need to use _.ary? Why doesn’t my initial attempt work?

Advertisement

Answer

The _.partialRight method can still accept more arguments than the new function should expect. If a function takes two arguments, has one or two partially applied, then any extra arguments effectively “bump off” the partially applied ones:

JavaScript
JavaScript

This happens because _.partialRight effectively adds to the end of the arguments object:

JavaScript
JavaScript

Thus the function constructed by _.partialRight is susceptible to the same problem that passing parseInt as callback has – more arguments can be passed in and will be passed in, since the callback for _.map always passes the element, the index, and the array. Therefore even though _.partialRight(_.groupBy, 'id') should have the second argument set to 'id', when _.map calls the function as callback(item, index, array) it turns into the fourth argument. And effectively the callback that gets executed is

JavaScript

This is why clamping down the arity with _.ary(fn, 1) or directly with _.unary() works – the extra arguments from _.map() would be discarded in that case and only the first one would be processed:

JavaScript
JavaScript

For the record, if you prefer more functional style and point-free style then you can use the Lodash FP distribution of Lodash which makes this easier. All the exported functions are curried and the arguments are changed so data is always last. Which allows you to more easily construct the processing for given data:

JavaScript
JavaScript
JavaScript
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement