We can define another parameter named `accumulator`
The accumulator is defined to store grouped data, which should be {} by default:
['one', 'two', 'three'].groupBy(i => i.length); // => {3: Array(2), 5: Array(1)}
['one', 'two', 'three'].groupBy(i => i.length, {}); // => {3: Array(2), 5: Array(1)}
['one', 'two', 'three'].groupBy(i => i.length, []); // => [empty × 3, Array(2), empty, Array(1)]
['one', 'two', 'three'].groupBy(i => i.length === 3 ? 0 : 1, []); // => [Array(2), Array(1)]
Arrays with holes, like in №3, are evil. For use cases like №4, you could use .reduce.
.reduce is not convenient so much, and that's why we want to produce .groupBy.
['one', 'two', 'three'].reduce((acc, i) => {
(acc[i.length] = acc[i.length] || []).push(i);
return acc;
}, {}); // => {3: Array(2), 5: Array(1)}
['one', 'two', 'three'].reduce((acc, i) => {
(acc[i.length === 3 ? 0 : 1] = acc[i.length === 3 ? 0 : 1] || []).push(i);
return acc;
}, []); // => [Array(2), Array(1)]
You could use just
Object.assign([], ['one', 'two', 'three'].groupBy(i => i.length));
Usage of already existing inner array-accumulators is too specific use case.
In reduce, the user chooses to modify or replace the accumulator - having the engine do the mutations would be very bad for a number of reasons.
In my opinion, it is just a similar definition like an accumulator, with which I hope to define to describe such a group: an object or an array.
The other issue is that, the reduce's accumulator is very general purpose. You can use an object, an array, a number, a string, a map, etc. Really, any value can be an accumulator in reduce(). The accumulator parameter you're proposing for .groupBy() can only be either an object or an array, and there really aren't many use cases for using an array as an accumulator. (Your 4th example seems incorrect when it uses [[], []] for the accumulator - if it were consistent with the third example, the accumulator would just be []).
OK, @theScottyJam I should modify the example above, but if passing a string, is this a use case?
['one', 'two', 'three'].groupBy((v, i) => i, '123'); // => 'one1two2three3'
If you have to ask, it’s probably not :-)
the most useful 4th case could be solved by this suggestion
@MaxGraey It seems like a same idea with a different way of defining a separated method.