Samuel
Samuel

Reputation: 1436

grouping objects using lodash

I have an array userList:

[
  {email : '[email protected]',
  department : 'd1'},
  {email : '[email protected]',
  department : 'd2'},
  {email : '[email protected]',
  department : 'd1'},
]

I wanted it to be like :

[
  {
  email : '[email protected]',
  department : ['d1','d2']
  },
  {
  email : '[email protected]',
  department : ['d1']
  }
]

I achieved it using :

const userGrp = _.groupBy(userList, 'email');
let data = [];
for (let key in userGrp) {
    if (userGrp.hasOwnProperty(key)) {
        const obj = {
            email: key,
            dept: extractDept(userGrp[key]),
        };
        data.push(obj);
    }
}

function extractDept(userObjList) {
  const arr = [];
  userObjList.forEach((element) => {
    arr.push(element.departmentName);
  });
  return arr;
}

How can I acheive it using lodash ?

Upvotes: 0

Views: 73

Answers (3)

Akrion
Akrion

Reputation: 18525

With Lodash grouping on email and using entries and the "maping" to get the required output:

const data = [{ email: '[email protected]', department: 'd1' }, { email: '[email protected]', department: 'd2' }, { email: '[email protected]', department: 'd1' }, ]

const result = _(data)
  .groupBy('email')
  .entries()
  .map(([k,v]) => ({email: k, departments: _.map(v, 'department')}))
  .value()

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

With ES6:

const data = [{ email: '[email protected]', department: 'd1' }, { email: '[email protected]', department: 'd2' }, { email: '[email protected]', department: 'd1' }, ]

const grp = data.reduce((r,c) => (r[c.email] = [...r[c.email] || [], c], r), {})
console.log(Object.entries(grp).map(([k,v]) => 
   ({email: k, departments: v.map(x => x.department)})))

Upvotes: 0

Houssein Zouari
Houssein Zouari

Reputation: 722

Here is a working example with Lodash : http://jsfiddle.net/houssein/u4dzLk2b/1/

   var data = [
      {email : '[email protected]',
      department : 'd1'},
      {email : '[email protected]',
      department : 'd2'},
      {email : '[email protected]',
      department : 'd1'},
    ];

    var result = _.chain(data)
        .groupBy("email")
        .pairs()
        .map(function (currentItem) {
            return _.object(_.zip(["email", "departement"], currentItem));
        })
        .value();
    console.log(result);

Upvotes: 0

baao
baao

Reputation: 73301

Since it's quite easy using plain js, here's the plain js way to group as you like

const grouped = [...foo.reduce((a, {email, department}) =>
     a.set(email, (a.get(email) || []).concat(department))
, new Map)].map(([email, department]) => ({email, department}));

console.log(grouped)
<script>
const foo = [
    {email : '[email protected]',
        department : 'd1'},
    {email : '[email protected]',
        department : 'd2'},
    {email : '[email protected]',
        department : 'd1'},
];

</script>

Upvotes: 2

Related Questions