Skip to content Skip to sidebar Skip to footer

Grouping By Using Lodash

I have an array of objects as follows: var data = [ { 'count': 1, 'make': 'ALFA ROMEO', 'model': 'GIULIETTA DIESEL - 2010' }, { 'count': 2, 'make': 'A

Solution 1:

You can achive that with combination of lodash groupBy and sumBy

var result = _.chain(data)
        .groupBy("make")
        .map( (element, id) => ({
            make: id,
            count: _.sumBy(element, 'count'),
        }))
        .value();

console.log(result);

[
  {
    "make": "ALFA ROMEO",
    "count": 1
  },
  {
    "make": "AUDI",
    "count": 5
  },
  {
    "make": "Volkswagen",
    "count": 3
  },
  {
    "make": "Ford",
    "count": 3
  },
  {
    "make": "Opel",
    "count": 2
  }
]

Solution 2:

Using lodash

Start a lodash chain. Use _.groupBy() by the make, then _.map() the results, and _.sumBy() the count properties. Convert back to an array using _.values(), sort descending with _.orderBy(), and use _.value() to finish the chain. Split the results into 2 arrays, and sum the 2nd array (the lowset counts) using reduce:

var data = [{"count":1,"make":"ALFA ROMEO","model":"GIULIETTA DIESEL - 2010"},{"count":2,"make":"AUDI","model":"A1 DIESEL"},{"count":1,"make":"AUDI","model":"A1 SPORTBACK DIESEL"},{"count":2,"make":"AUDI","model":"A3 DIESEL - 2012"},{"count":3,"make":"Volkswagen","model":"Golf"},{"count":3,"make":"Ford","model":"Escord"},{"count":2,"make":"Opel","model":"Zafira"}];

var counts = _(data)
  .groupBy('make')
  .map(function(g, key) { return {
      make: key,
      count: _.sumBy(g, 'count')
  };})
  .values()
  .orderBy('count', 'desc')
  .value();
  
var result = counts.slice(0, 3).concat({
  brand: 'other',
  count: counts.slice(3).reduce(function(s, { count }) { return s + count; }, 0)
})
  
console.log(result);
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Using ES6

Iterate with Array#reduce, collect all the make count values to an object in a Map, then get the map values iterator, and spread to get an array, and sort descending. Split the results into 2 arrays, and sum the 2nd array (the lowset counts) using reduce:

const data = [{"count":1,"make":"ALFA ROMEO","model":"GIULIETTA DIESEL - 2010"},{"count":2,"make":"AUDI","model":"A1 DIESEL"},{"count":1,"make":"AUDI","model":"A1 SPORTBACK DIESEL"},{"count":2,"make":"AUDI","model":"A3 DIESEL - 2012"},{"count":3,"make":"Volkswagen","model":"Golf"},{"count":3,"make":"Ford","model":"Escord"},{"count":2,"make":"Opel","model":"Zafira"}];

const counts = [...data.reduce((m, { make, count }) => {
  const item = m.get(make) || { make, count: 0 };
  
  item.count += count;

  return m.set(make,  item);
}, newMap()).values()].sort((a, b) => b.count - a.count);

const result = counts.slice(0, 3).concat({
  brand: 'other',
  count: counts.slice(3).reduce((s, { count }) => s + count, 0)
})

console.log(result);

Solution 3:

With plain Javascript, you could take a hash table for collecting same make and sort the result array. Later add all counts which are at the end of the result set until the array gets a wanted length.

var data = [{ count: 1, make: "ALFA ROMEO", model: "GIULIETTA DIESEL - 2010" }, { count: 2, make: "AUDI", model: "A1 DIESEL" }, { count: 1, make: "AUDI", model: "A1 SPORTBACK DIESEL" }, { count: 2, make: "AUDI", model: "A3 DIESEL - 2012" }, { count: 3, make: "Volkswagen", model: "Golf" }, { count: 3, make: "Ford", model: "Escord" }, { count: 2, make: "Opel", model: "Zafira" }],
    hash = Object.create(null),
    result = [];

data.forEach(function (car) {
    if (!hash[car.make]) {
        hash[car.make] = { make: car.make, count: 0 };
        result.push(hash[car.make]);
    }
    hash[car.make].count += car.count;
});

result.sort(function (a, b) {
    return b.count - a.count;
});

while (result.length > 4) {
    result.push({ make: 'Other', count: result.pop().count + result.pop().count });
}

console.log(result);
.as-console-wrapper { max-height: 100%!important; top: 0; }

Post a Comment for "Grouping By Using Lodash"