Search code examples
javascriptarraysjsonobjectlodash

Lodash keyBy same properties as arrays


I have a few objects in an array:

"surcharges": [
    {
        "supplier": "XXXXX",
        "name": "over_pkg_0",
        "amount": 230
    },
    {
        "supplier": "XXXXX",
        "name": "over_pkg_1",
        "amount": 54
    },
    {
        "supplier": "YYYYY",
        "name": "over_pkg_0",
        "amount": 25
    },
    {
        "supplier": "YYYYY",
        "name": "over_pkg_1",
        "amount": 25
    }
];

I would like to get the following results using lodash:

"surcharges": [
    {
        "XXXXX": [
            {
                "name": "over_pkg_0",
                "amount": 230
            },
            {
                "name": "over_pkg_1",
                "amount": 54
            }
        ],
    },
    {
        "YYYYY": [
            {
                "name": "over_pkg_0",
                "amount": 25
            },
            {
                "name": "over_pkg_1",
                "amount": 25
            }
        ],
    }
];

I'm able to produce something similar, but the keys are getting merged and I'm unable to make them an array. Probaly I should use _.concat somewhere in the chain, but I'm unable to figure out how.

Tried using:

var finalsurcharges = _.chain(surcharges)
  .keyBy('supplier')
  .mapValues(v => _.omit(v, 'supplier'))
  .value();

Produces:

"finalsurcharges": {
    "XXXXX": {
        "name": "over_pkg_1",
        "amount": 54
    },
    "YYYYY": {
        "name": "over_pkg_1",
        "amount": 25
    }
}

Solution

  • Use _.groupBy() to group an array of objects by a key value:

    const data = { surcharges: [{"supplier":"XXXXX","name":"over_pkg_0","amount":230},{"supplier":"XXXXX","name":"over_pkg_1","amount":54},{"supplier":"YYYYY","name":"over_pkg_0","amount":25},{"supplier":"YYYYY","name":"over_pkg_1","amount":25}]};
    
    const finalsurcharges = _(data.surcharges)
        .groupBy('supplier')
        .mapValues((g) => g.map(o => _.omit(o, 'supplier')))
        .value();
    
    console.log(finalsurcharges);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>