使用reduce基于一键合并数组中的对象

Merge objects in array based on one key using reduce

我有对象数组:

[{sku: "BS-WHITE-1", GB: 15, total: 0, inbound: 0, available: 0, …},
{sku: "BS-WHITE-1", DE: 4},
{sku: "BS-WHITE-1", ES: 0},
{sku: "BS-WHITE-1", IT: 3},
{sku: "BS-WHITE-1", FR: 0},
{sku: "BS-WHITE-2", GB: 19, total: 40, inbound: 0, available: 40, …}
{sku: "BS-WHITE-2", DE: 2},
{sku: "BS-WHITE-2", FR: 5},
{sku: "BS-WHITE-2", ES: 3},
{sku: "BS-WHITE-2", IT: 6},
{sku: "BS-WHITE-3", GB: 21, total: 51, inbound: 1, available: 50, …}
{sku: "BS-WHITE-3", DE: 1},
{sku: "BS-WHITE-3", ES: 1},
{sku: "BS-WHITE-3", IT: 2},
{sku: "BS-WHITE-3", FR: 2},
{sku: "BS-WHITE-4", GB: 43, total: 42, inbound: 8, available: 31, …},
{sku: "BS-WHITE-4", DE: 8},
{sku: "BS-WHITE-4", FR: 7},
{sku: "BS-WHITE-4", ES: 3},
{sku: "BS-WHITE-4", IT: 17}]

我想根据键“sku”合并对象得到

[{sku: "BS-WHITE-1", GB: 15, DE: 4,ES: 0,IT: 3, FR: 0, total: 0, …},
{sku: "BS-WHITE-2", GB: 19, DE: 2,ES: 3,IT:6, FR: 5, total: 0, …},
{sku: "BS-WHITE-3", GB: 21, DE: 1,ES: 1,IT:2, FR: 2, total: 0, …},
{sku: "BS-WHITE-4", GB: 43, DE: 8,ES: 3,IT:17, FR: 7, total: 0, …}]

为此我使用 reduce

const out = map.reduce((a, v) => {
  if (a[v.sku]) {
    a[v.sku].GB = a[v.sku].GB; //ok
    a[v.sku].DE = (v.DE) ? v.DE : 222; //?
    a[v.sku].FR = a[v.sku].FR ? a[v.sku].FR : 555; //?
    a[v.sku].IT = 2; //
    a[v.sku].ES = a[v.sku].ES; //?
  } else {
    a[v.sku] = v;
  }
  return a;
}, {});
console.log(Object.values(out));
<script>
const map = [{sku: "BS-WHITE-1", GB: 15, total: 0, inbound: 0, available: 0 },
    {sku: "BS-WHITE-1", DE: 4},
    {sku: "BS-WHITE-1", ES: 0},
    {sku: "BS-WHITE-1", IT: 3},
    {sku: "BS-WHITE-1", FR: 0},
    {sku: "BS-WHITE-2", GB: 19, total: 40, inbound: 0, available: 40},
    {sku: "BS-WHITE-2", DE: 2},
    {sku: "BS-WHITE-2", FR: 5},
    {sku: "BS-WHITE-2", ES: 3},
    {sku: "BS-WHITE-2", IT: 6},
    {sku: "BS-WHITE-3", GB: 21, total: 51, inbound: 1, available: 50},
    {sku: "BS-WHITE-3", DE: 1},
    {sku: "BS-WHITE-3", ES: 1},
    {sku: "BS-WHITE-3", IT: 2},
    {sku: "BS-WHITE-3", FR: 2},
    {sku: "BS-WHITE-4", GB: 43, total: 42, inbound: 8, available: 31},
    {sku: "BS-WHITE-4", DE: 8},
    {sku: "BS-WHITE-4", FR: 7},
    {sku: "BS-WHITE-4", ES: 3},
    {sku: "BS-WHITE-4", IT: 17}]
</script>    

很遗憾,我找不到其他对象中的键 DE、FR、IT、ES 的值。只有第一个 GB 可以。有帮助吗?

您可以将对象分配给组或为该组生成新对象。

const
    data = [{ sku: "BS-WHITE-1", GB: 15, total: 0, inbound: 0, available: 0 }, { sku: "BS-WHITE-1", DE: 4 }, { sku: "BS-WHITE-1", ES: 0 }, { sku: "BS-WHITE-1", IT: 3 }, { sku: "BS-WHITE-1", FR: 0 }, { sku: "BS-WHITE-2", GB: 19, total: 40, inbound: 0, available: 40 }, { sku: "BS-WHITE-2", DE: 2 }, { sku: "BS-WHITE-2", FR: 5 }, { sku: "BS-WHITE-2", ES: 3 }, { sku: "BS-WHITE-2", IT: 6 }, { sku: "BS-WHITE-3", GB: 21, total: 51, inbound: 1, available: 50 }, { sku: "BS-WHITE-3", DE: 1 }, { sku: "BS-WHITE-3", ES: 1 }, { sku: "BS-WHITE-3", IT: 2 }, { sku: "BS-WHITE-3", FR: 2 }, { sku: "BS-WHITE-4", GB: 43, total: 42, inbound: 8, available: 31 }, { sku: "BS-WHITE-4", DE: 8 }, { sku: "BS-WHITE-4", FR: 7 }, { sku: "BS-WHITE-4", ES: 3 }, { sku: "BS-WHITE-4", IT: 17 }],
    result = Object.values(data.reduce((r, o) => {
        Object.assign(r[o.sku] ??= {}, o);
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

这里有一个使用Array.prototype.reduce来改变数组的形状

let data = [
    {sku: "BS-WHITE-1", GB: 15, total: 0, inbound: 0, available: 0},
    {sku: "BS-WHITE-1", DE: 4},
    {sku: "BS-WHITE-1", ES: 0},
    {sku: "BS-WHITE-1", IT: 3},
    {sku: "BS-WHITE-1", FR: 0},
    {sku: "BS-WHITE-2", GB: 19, total: 40, inbound: 0, available: 40},
    {sku: "BS-WHITE-2", DE: 2},
    {sku: "BS-WHITE-2", FR: 5},
    {sku: "BS-WHITE-2", ES: 3},
    {sku: "BS-WHITE-2", IT: 6},
    {sku: "BS-WHITE-3", GB: 21, total: 51, inbound: 1, available: 50},
    {sku: "BS-WHITE-3", DE: 1},
    {sku: "BS-WHITE-3", ES: 1},
    {sku: "BS-WHITE-3", IT: 2},
    {sku: "BS-WHITE-3", FR: 2},
    {sku: "BS-WHITE-4", GB: 43, total: 42, inbound: 8, available: 31},
    {sku: "BS-WHITE-4", DE: 8},
    {sku: "BS-WHITE-4", FR: 7},
    {sku: "BS-WHITE-4", ES: 3},
    {sku: "BS-WHITE-4", IT: 17}
];

const result = data.reduce((accumulator, current) => {
    let itemIndex = accumulator.findIndex(item => item.sku === current.sku);
    if(itemIndex != -1) {
        accumulator[itemIndex] = {...accumulator[itemIndex], ...current};
    } else {
        accumulator = accumulator.concat(current);
    }
    return accumulator;
}, []);

console.log(result);