Search code examples
javascriptmomentjslodash

group array of object by dates


I have a data structure that look like this

const arr = [{
    name: "Alice",
    created_at : "2017-04-18"
},
{
    name: "James",
    created_at : "2017-06-30"
},
{
    name: "Melisa",
    created_at : "2017-04-03"
},
{
    name: "Amy",
    created_at : "2017-05-03"
}];

I want to restructure it so that I can display them. I want to display them by month, like so

April - Alice - Melisa

May - Amy

June - James

I have no clue where to begin.


Solution

  • Here's a solution that uses moment and lodash.

    First we create a helper function that uses moment to create a date and then then extract the shortened month name.

    // helper function to get the month name from an item
    const monthName = item => moment(item.created_at, 'YYYY-MM-DD').format('MMM');
    

    Now use lodash to group by date and then map across each group to get the names for each group. The following snippet uses implicit chaining:

    // group items by month name and then get the name for each month
    const result = _(arr)
        .groupBy(monthName)
        .mapValues(items => _.map(items, 'name'))
        .value()
    

    As above but with explicit chaining:

    // group items by month name and then get the name for each month
    const result = _.chain(arr)
        .groupBy(monthName)
        .mapValues(items => _.map(items, 'name'))
        .value()
    

    UPDATE

    To get all the items for each month then it simplifies to just this:

    const result = _.groupBy(arr, monthName);
    

    result will now look like this:

    {
        Apr: [
            { name: "Alice", created_at : "2017-04-18" },
            { name: "Melisa", created_at : "2017-04-03" }
        ],
        Jun: .....
    }