如何按键对对象数组进行分组并在其中创建另一个对象

How can I group an array of objects by key and create another object inside

有谁知道如何通过对象键对对象数组进行分组,然后根据分组创建新的对象数组?例如,我有一个如下所示的 Build 对象数组,我想按产品分组并基于此创建另一个颜色和价格对象。

build = [
    {
        'Product': 'Cabinets',
        'Color': 'Blue',
    }, 
    {
        'Product': 'CounterTop',
        'Color': 'White',
    }, 
    {
        'Product': 'Cabinets',
        'Color': 'Yellow',
    }, 
    {
        'Product': 'Cabinets',
        'Color': 'Yellow',
    }
]

我想要这样

[
  {
     'Product':'Cabinet',
     'color' : { 'Blue','Yellow' }
  },
  {
     'Product':'CounterTop',
     'color' : { 'White' }
  }
]

我写了一个代码来存档它,但我没有得到预期的结果。

build.forEach(pr => {
                if (pr.Product in result) {
                    result[pr['Product']]['Color'] = pr['Color'];
                }
                else {
                    result[pr['Product']] = {
                        'Product': pr['Product'],
                        'Color': pr['Color'] 
                    }
                }
            });

以上代码returns

 [
  {
     'Product':'Cabinet',
     'color' : 'Yellow' 
  },
  {
     'Product':'CounterTop',
     'color' : 'White'
  }
]

在您的输出中期望 'color' : { 'Blue','Yellow' } 是错误的。对象是 key-value 对数据。

相反,您希望 color 是一个数组。我调整了你的代码:

build.forEach(pr => {
  if (pr.Product in result) {
      result[pr['Product']]['Color'].push(pr['Color']);
  } else {
      result[pr['Product']] = {
          'Product': pr['Product'],
          'Color': [pr['Color']]
      }
  }
});

现在考虑一下如何防止数组中出现重复值。 @Lissy93 的回答通过使用 findIndex.

来帮助解决这个问题

这是一个工作版本。希望对您有所帮助:)

const builds = [
    { 'Product': 'Cabinets', 'Color': 'Blue' }, 
    { 'Product': 'CounterTop', 'Color': 'White' }, 
    { 'Product': 'Cabinets', 'Color': 'Yellow' }, 
    { 'Product': 'Cabinets', 'Color': 'Yellow' }
];

const results = [];

builds.forEach((build) => {
  const index = results.findIndex((b) => b.Product === build.Product);
  if (index === -1) {
    results.push({Product: build.Product, Color: [ build.Color ]});
  } else {
    results[index] = {Product: build.Product, Color: [ ...results[index].Color, build.Color ]}
  }
});

console.log(results);

您代码中的主要问题是您将数组和 key-value-pairs 与 color 混淆了。 KVP 看起来像 { color: 'red' },而数组将是:[ 'red', 'blue'].

使用这个策略:

  • 寻找独特的产品
  • 根据独特的产品使用 Array#mapArray#filter 构建所需的数据

参见下面的演示:

const builds = [ { 'Product': 'Cabinets', 'Color': 'Blue' }, { 'Product': 'CounterTop', 'Color': 'White' }, { 'Product': 'Cabinets', 'Color': 'Yellow' }, { 'Product': 'Cabinets', 'Color': 'Yellow' } ],

      output = [...new Set(builds.map(({Product}) => Product))]
      .map(Product =>
          ({
              Product, 
              Color:builds.filter(({Product:P}) => P === Product)
              .map(({Color}) => Color)
           })
       );

console.log(output);