senior_script
senior_script

Reputation: 151

How group and count elements by lodash?

My data:

[{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }, {
    id: 1,
    name: 'foo'
  }
];

I want to do something like this:

[
  {
    name: "foo",
    id: 1,
    count: 2
  },
  {
    name: "bar",
    id: 2,
    count: 1
  }
]

Now i'm grouping the elements with groupBy by name.

Thanks for the help!

Upvotes: 0

Views: 878

Answers (3)

jsN00b
jsN00b

Reputation: 3691

With deference to the answer provided here which uses 'lodash', as requested in the above question, the below points are observed:

  1. the 'groupBy' is fixed (ie, the 'name' field/column/prop) is used
  2. the result given includes the name & count, but the expected result needs the 'id' as well.

EDIT: Adding solution using lodash,

const arrayRaw = [{
  id: 1,
  name: 'foo'
}, {
  id: 2,
  name: 'bar'
}, {
  id: 1,
  name: 'foo'
}];

const groupBy = (col = 'name', arr = arrayRaw) => (
  _(arr).groupBy(col).map(it => ({
    ...it[0],
    count: it.length
  })).value()
);

console.log(groupBy());
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/1.2.1/lodash.min.js"></script>

In case, someone requires a solution without 'lodash', the below should be one possible implementation:

const arrayRaw = [{
  id: 1,
  name: 'foo'
}, {
  id: 2,
  name: 'bar'
}, {
  id: 1,
  name: 'foo'
}];

const groupBy = (col = 'name', arr = arrayRaw) => (
  Object.entries(arr.reduce((fin, itm, idx) => ({
    ...fin,
    [itm[col]]: (fin[itm[col]] || []).concat([idx])
  }), {})).map(([k, v]) => ({
    ...arr[v[0]],
    count: v.length
  }))
);

console.log(groupBy());

Approach / Explanation It is self-explanatory, however, should anyone require one - please comment and I shall add.

Upvotes: 0

mstephen19
mstephen19

Reputation: 1926

It's not exactly what you asked for, but here is a simple method without using lodash. Here I'm using the ID of each element, but you can use anything that uniquely identifies it.

const objArray = [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }, {
    id: 1,
    name: 'foo'
  }
];

const reduceAndCount  = (arr) => {
    const newMap = {};
    arr.forEach(el => {
        if (!newMap[el.id]) {
            el.count = 1
            return newMap[el.id] = el
        }
        newMap[el.id].count = newMap[el.id].count + 1
    })
    return Object.values(newMap)
}

const result = reduceAndCount(objArray)
console.log(result)

Upvotes: 0

jeremy-denis
jeremy-denis

Reputation: 6878

var source = [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }, {
    id: 1,
    name: 'foo'
  }
];
  
var result = _(source)
    .groupBy('name')
    .map(function(items, name) {
      return {
        name: name,
        count: items.length
        }
     }).value();

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Upvotes: 2

Related Questions