0

The following code allows to count each occurrence in an array by returning an array of array :

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var result = [...a.reduce( (m, v) => m.set(v, (m.get(v) || 0) + 1), new Map() )];
console.log(result);

Result : [ [ 5, 3 ], [ 2, 5 ], [ 9, 1 ], [ 4, 1 ] ]

As reduce function takes previousValue, currentValue, currentIndex, array, does it mean :

m = previousValue

v = currentValue

new Map() = array ?

I can't crack the logic here.

Thanks

fransua
  • 501
  • 2
  • 18
  • 2
    `new Map()` is the initial value for `m` (which is previousValue) used in the first iteration of this code. – VLAZ Aug 03 '22 at 12:26
  • 2
    FWIW it doesn't help code comprehension when it's all on one line like that. – Andy Aug 03 '22 at 12:30

1 Answers1

-2

"does it mean: m = previousValue v = currentValue"

That's correct. JavaScript often lets you omit arguments from the end of the list if you're not actually going to use them. For more, see the documentation for reduce here, which clarifies with some examples:

reduce((previousValue, currentValue) => { /* … */ } )
reduce((previousValue, currentValue, currentIndex) => { /* … */ } )
reduce((previousValue, currentValue, currentIndex, array) => { /* … */ } )

"new Map() = array?"

No, the map is the initial value, and in the context of the reducer function, the previousValue. It manages to continue to be the previousValue, because map.set returns the map again, and the return result of the reducer function is used as the previousValue on subsequent calls.

Honestly, this feels like a misuse of reduce. Just create a map, iterate over each item in the list. It calls for foreach, not reduce.

Luke
  • 1,724
  • 1
  • 12
  • 17
  • 2
    It is *not* correct `new Map()` is not `array` – VLAZ Aug 03 '22 at 12:28
  • OK, I think the substance of the question was "what's up with these arguments". – Luke Aug 03 '22 at 12:29
  • 1
    And you confirmed that the initialiser is a completely unrelated parameter. – VLAZ Aug 03 '22 at 12:29
  • I don't want to argue the semantics of unrelated. But you're correct that my answer could be extended to discuss the map further. – Luke Aug 03 '22 at 12:33
  • 1
    The nice thing about using `.reduce()` (and yes this is a matter of opinion) is that all the work is contained in a single expression, without any need for a variable in a surrounding lexical context. That `.reduce()` expression could be an argument to another function, for example, and the local scope my not need that intermediate result at all. – Pointy Aug 03 '22 at 12:38
  • I guess it is one statement, but you're rarely working with a statements budget, and I do think it hurts readability here. Clearly I'm coming from a very procedural base :D – Luke Aug 03 '22 at 12:43