Showcaselfloyd Showcaselfloyd -4 years ago 89
Javascript Question

How to return an array of objects aggregating over a larger dataset in JavaScript using the reduce

I'm iterating over a large dataset using the reduce() method. I'm trying to count all the names in a dataset and return each name as an object with the total number.

Here's the rub. It reduces the dataset down to the names, but doesn't count the number.

var countedNames = __dataset.reduce(function (allBeers, beer) {
let t=0;
if (beer in allBeers) {
allBeers[ beer ] = {"name": beer,"count": t++};
} else {
allBeers[ beer ] = {"name": beer,"count": 1};
}
return allBeers;
}, []);

Answer Source

First off, your accumulator allBears is initialized as an array. From the code you started with, it seems you would rather have an object. So, noticed I changed the last line from [] to {}.

Second, you are returning an undefined variable named allNames inside your reduce function.

The following code should work (assuming __dataset is an array of strings).

var countedNames = __dataset.reduce(function (allBeers, beer) {

  let count = allBeers.hasOwnProperty(beer) ? allBeers[beer].count + 1 : 0;
  allBeers[beer] = { name : beer, count : count }
  return allBeers;
}, {});

This will result in..

var __dataset = ["a", "b", "a", "b", "c", "c", "c"];

{
  a: {
    name: "a",
    count: 2,
  },
  b: {
    name: "b",
    count: 2,
  },
  a: {
    name: "c",
    count: 3,
  }
}

If you want an array of objects (like a table structure), you can iterate on the result like so.

var results = Object.keys(countedNames)
  .map(function(key) {
    return countedNames[key];
  });

This will yield an array like this...

[
  { name: "a", count: 2 },
  { name: "b", count: 2 },
  { name: "c", count: 3 }
]

Here's a JS Bin. http://jsbin.com/segudeqiva/edit?js,console

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download