1

The title might seem quite verbose, but in reference to this answer posted in this question: https://stackoverflow.com/a/37623524/4111415

I was wondering what the let count = prev.get(curr.key) || 0; actually meant. As far as I am aware the accumulator (prev) is just a number; what is the get method actually doing here? I have looked at the MDN documenation to no avail: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

let objArr = [
  {key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 42},
  {key: 'Mon Sep 24 2013 00:00:00 GMT-0400', val: 78},
  {key: 'Mon Sep 25 2013 00:00:00 GMT-0400', val: 23},
  {key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 54}
];

// first, convert data into a Map with reduce
let counts = objArr.reduce((prev, curr) => {
  let count = prev.get(curr.key) || 0;
  prev.set(curr.key, curr.val + count);
  return prev;
}, new Map());

// then, map your counts object back to an array
let reducedObjArr = [...counts].map(([key, value]) => {
  return {key, value}
})

console.log(reducedObjArr);
James Stott
  • 129
  • 1
  • 7
  • In your code, it's https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get. `new Map()`, the initial value, is not a number! – Bergi Jan 25 '19 at 11:28
  • If you vote down, specify the reason or edit the question please. I don't see any reason to do that here. – Stav Alfi Jan 25 '19 at 11:30

4 Answers4

1

As far as I am aware the accumulator (prev) is just a number

No, this isn't always the case. If a value is specified in the initialValue argument of .reduce, the accumulator (in this case prev) will take the value of that initial value.

The initial value in your example is new Map() which is a map object. The Map prototype includes the .get method, which is used to retrieve a specific value from the map object (similar to object key-value pair retrieval).

Thus, your .get method is referring to the Map object, not a number.

Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
0

prev, i.e the accumulator, is actually a Map object, which is passed as the last parameter to the .reduce() function.

Leo
  • 741
  • 6
  • 14
0

In the provided example the accumulator is an instance of Map object (instead of a number), that is being passed as a last argument (initial value) to reduce.

antonku
  • 7,377
  • 2
  • 15
  • 21
0

Map#get is part of the prototype of Map.

You could simplify the reduce by returning the map directly, because of the fluent interface of Map#set.

For getting a formatted result, you could use Array.from with mapping function.


Maybe you are a bit irritated by the use of prev and curr. If you take instead map and item, you might get better the types of the variables.

let objArr = [{ key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 42 }, { key: 'Mon Sep 24 2013 00:00:00 GMT-0400', val: 78 }, { key: 'Mon Sep 25 2013 00:00:00 GMT-0400', val: 23 }, { key: 'Mon Sep 23 2013 00:00:00 GMT-0400', val: 54 }],
    counts = objArr.reduce(
        (map, item) => map.set(item.key, item.val + (map.get(item.key) || 0)),
        new Map
    ),
    reducedObjArr = Array.from(counts, ([key, value]) => ({ key, value }));

console.log(reducedObjArr);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392