简体   繁体   中英

Lodash - Aggregate values in JSON object without specifying keys

I am trying to get a sum of values in a JSON array grouped by a shop_id and key, and get the output in the same format. I tried doing it on the DB since I am not familiar with Lodash at all but I reckon sending and receiving data from DB would not be as efficient.

With an array like this:

[
    {
        sales: {"bicycle": 2, "skateboard": 5},
        shop_id: 6321
    },
    {
        sales: {"bicycle": 1, "skateboard": 3},
        shop_id: 6243
    },
    {
        sales: {"bicycle": 3, "skateboard": 4},
        shop_id: 6243
    }
]

The output should look like:

[
    {
        sales: {"bicycle": 2, "skateboard": 5},
        shop_id: 6321
    },
    {
        sales: {"bicycle": 4, "skateboard": 7},
        shop_id: 6243
    }
]

How can I achieve this with Lodash? Or are there better ways to handle it without it?

This should work:

What it does is:

  • Creates an empty accumulator object
  • Loops trough the array and puts each value at [shop_id] position in the accumulator
  • If there's an object already at that position, then merges them
  • Gets just the values of the accumulator object to make an array

 const input = [ { sales: {"bicycle": 2, "skateboard": 5}, shop_id: 6321 }, { sales: {"bicycle": 1, "skateboard": 3}, shop_id: 6243 }, { sales: {"bicycle": 3, "skateboard": 4}, shop_id: 6243 } ]; // Output of input.reduce is an object. To get array we simply just use the values in this object const output = Object.values( // Array.prototype.reduce loops through the array // And ads all the values into the acumulator by running your custom function input.reduce( // Custom accumulator function (accumulator, value) => { // If there's already an object at this position (position is the unique shop_id) if (accumulator[value.shop_id]) { // Merge the old and the new object // Loop through all the keys of the new object Object.entries(value.sales).forEach( ([key, number]) => { // If this key is already present in the old object if (accumulator[value.shop_id].sales[key]) { // Sum the old and the new value accumulator[value.shop_id].sales[key] += number; } else { // Set the key to the new value accumulator[value.shop_id].sales[key] = number; } } ); // There is no object yet at this position } else { // Make a deep copy to avoid modifiing the input // And put it at this position accumulator[value.shop_id] = { shop_id: value.shop_id, sales: {...value.sales }, }; } // Return the modified acumulator return accumulator; }, {} //The initial accumulator (empty object) ) ); console.log(output);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM