Lodash - 在不指定键的情况下聚合 JSON 对象中的值

Lodash - Aggregate values in JSON object without specifying keys

我正在尝试获取按 shop_id 和键分组的 JSON 数组中值的总和,并以相同的格式获取输出。我尝试在数据库上执行此操作,因为我根本不熟悉 Lodash,但我认为从数据库发送和接收数据的效率不会那么高。

使用这样的数组:

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

输出应如下所示:

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

我如何使用 Lodash 实现这一目标?或者有没有更好的方法来处理它?

这应该有效:

它的作用是:

  • 创建一个空的累加器对象
  • 遍历数组并将每个值放在累加器中的 [shop_id] 位置
  • 如果那个位置已经有对象,则合并它们
  • 仅获取累加器对象的值以构成数组

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);