Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lodash - group and populate arrays

Tags:

lodash

Using lodash, how could I group the names of people that have the same birthdates as seen below?

I wrote this out using nested for loops but was thinking there would be a more elegant way of doing this in lodash. I haven't used it much and trying to figure out which function to use.

[
    { "birthdate": "1993", "name": "Ben" },
    { "birthdate": "1994", "name": "John" },
    { "birthdate": "1995", "name": "Larry" },
    { "birthdate": "1995", "name": "Nicole" },
    { "birthdate": "1996", "name": "Jane" },
    { "birthdate": "1996", "name": "Janet" },
    { "birthdate": "1996", "name": "Dora" },
]

to

[
    { "birthdate": "1993", "names": [ "Ben" ] }, 
    { "birthdate": "1994", "names": [ "John"] },
    { "birthdate": "1995", "names": [ "Larry", "Nicole" ] }, 
    { "birthdate": "1996", "names": [ "Jane", "Janet", "Dora" ] }        
]
like image 256
Thibs Avatar asked Feb 07 '17 03:02

Thibs


2 Answers

You can use groupBy() to group each item in the collection by birthdate. After grouping the items, you can use map() to iterate each groups and form them into a new format that includes a birthdate and names. To acquire an array of names from the grouped items, you can use the map() function again to return all the name values.

var result = _(source)
    .groupBy('birthdate')
    .map(function(items, bdate) {
      return {
        birthdate: bdate,
        names: _.map(items, 'name')
      };
    }).value();

var source = [
    { "birthdate": "1993", "name": "Ben" },
    { "birthdate": "1994", "name": "John" },
    { "birthdate": "1995", "name": "Larry" },
    { "birthdate": "1995", "name": "Nicole" },
    { "birthdate": "1996", "name": "Jane" },
    { "birthdate": "1996", "name": "Janet" },
    { "birthdate": "1996", "name": "Dora" },
];
  
var result = _(source)
    .groupBy('birthdate')
    .map(function(items, bdate) {
      return {
        birthdate: bdate,
        names: _.map(items, 'name')
      };
    }).value();

document.body.innerHTML = '<pre>' + JSON.stringify(result, 0, 4) + '</pre>';
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
like image 157
ryeballar Avatar answered Oct 23 '22 19:10

ryeballar


You can chain groupBy and map to achieve this.

_.chain(yourArray)
.groupBy('birthdate')
.toPairs()
.map(s=>{
return _.zipObject(['birthdate','names'],s)
})
.map(s=>{
s.names=_.map(s.names,x=>x.name);
return s;
})
.value()
like image 2
Waqas Noor Avatar answered Oct 23 '22 20:10

Waqas Noor