JS将具有动态键和值的对象推送到数组

JS push object with dynamic keys and values to an array

我有一个包含动态键和值的对象数组(因此并非所有对象都具有 category_id、大小等),但我将其简化为:

let products_row = [
  {
    id: 1,
    category_id: 11,
    options: {
      'modelName1': {
        size: '2 feet',
        colour: 'red',
        is_new: true
      },
      'modelName2': {
        size: '4 feet',
        colour: 'black',
        is_new: true
      },
    }
  },
  {
    id: 2,
    category_id: 21,
    options: {
      'modelName11': {
        size: '2 feet',
        colour: 'white',
        is_new: false
      },
      'modelName12': {
        size: '4 feet',
        colour: 'white',
        is_new: false
      },
    }
  },
  {
    id: 3,
    category_id: 31,
    options: {
      'modelName21': {
        size: '8 feet',
        colour: 'white',
        is_new: false
      },
      'modelName22': {
        size: '4 feet',
        colour: 'black',
        is_new: true
      },
    }
  },
  {
    id: 4,
    category_id: 41,
    options: {
      'modelName31': {
        size: '8 feet',
        colour: 'red',
        is_new: true
      },
      'modelName32': {
        size: '8 feet',
        colour: 'red',
        is_new: true
      },
    }
  }
]

结果数据结构需要是这样的:

let resultArray = [
  {
        id: 1,
        category_id: 11,
        model: 'modelName1',
        size: '2 feet',
        colour: 'red',
        is_new: true
  },
  {
        id: 1,
        category_id: 11,
        model: 'modelName2',
        size: '4 feet',
        colour: 'black',
        is_new: true
  },
  {
        id: 2,
        category_id: 21,
        model: 'modelName11',
        size: '2 feet',
        colour: 'white',
        is_new: false
 },
 {
        id: 2,
        category_id: 21,
        model: 'modelName12',
        size: '4 feet',
        colour: 'white',
        is_new: false
  },
  {
        id: 3,
        category_id: 31,
        model: 'modelName21',
        size: '8 feet',
        colour: 'white',
        is_new: false
  },
  {
        id: 3,
        category_id: 31,
        model: 'modelName22',
        size: '4 feet',
        colour: 'black',
        is_new: true
  },
  {
        id: 4,
        category_id: 41,
        model: 'modelName31',
        size: '8 feet',
        colour: 'red',
        is_new: true
  },
  {
        id: 4,
        category_id: 41,
        model: 'modelName32',
        size: '8 feet',
        colour: 'red',
        is_new: true
  },
]

这是我试过的:

let productsData = [];

products_row
.map((product, p) => Object.entries(product.options || {})
.filter((model, i) => {            
    return productsData.push(
      {
        model: model[0],          
        [Object.keys(product).filter(el => delete product.options)[i]]: Object.values(product)[i],
        [Object.keys(model[1] || [])[i]]: Object.values(model[1] || [])[i],
      }
    )
})
)

console.log(productsData)

但它 returns 不是所有数据,这是预期的,因为我不知道如何保留以前的键值:

[
  {      
        model: 'modelName1',
        id: 1,
        size: '2 feet',
  },
  {      
        model: 'modelName2',  
        category_id: 11,     
        colour: 'black',        
  },
  {     
        model: 'modelName11',
        id: 2,
        size: '2 feet',
 },
 {        
        model: 'modelName12',
        category_id: 21,
        colour: 'white',
  },
  {        
        model: 'modelName21',
        id: 3,
        size: '8 feet',
  },
  {        
        model: 'modelName22',
        category_id: 31,
        colour: 'black',
  },
  {        
        model: 'modelName31',
        id: 4,
        size: '8 feet',
  },
  {        
        model: 'modelName32',
        category_id: 41,
        colour: 'red',
  },
]

我完全卡住了,感谢任何帮助。谢谢。

您可以使用 flatMapmap
flatMap 所做的是如果 map 的返回数组看起来像

[
[{...1},{...2}],
[{...3},{...4}]
]

它会把它弄平并给出

[
{...1},{...2},
{...3},{...4}
]

let products_row = [{id: 1,category_id: 11,options: {'modelName1': {size: '2 feet',colour: 'red',is_new: true},'modelName2': {size: '4 feet',colour: 'black',is_new: true},}},{id: 2,category_id: 21,options: {'modelName11': {size: '2 feet',colour: 'white',is_new: false},'modelName12': {size: '4 feet',colour: 'white',is_new: false},}},{id: 3,category_id: 31,options: {'modelName21': {size: '8 feet',colour: 'white',is_new: false},'modelName22': {size: '4 feet',colour: 'black',is_new: true},}},{id: 4,category_id: 41,options: {'modelName31': {size: '8 feet',colour: 'red',is_new: true},'modelName32': {size: '8 feet',colour: 'red',is_new: true},}}]

let x = products_row.flatMap(({options,...rest}) => Object.entries(options).map(([k,v]) => ({...v,...rest,model:k})))

console.log(x)

很难分析你的解决方案和推理你的想法,所以我无法修复你的代码。

您想要做的是从每个对象中提取选项并附加对象的其余部分,换句话说,您想要迭代每个产品行的每个选项。

有很多方法可以实现这一点,您可以按照@cmgchess 的建议使用 flatMap。比较容易理解的是这样的:

let result = [];

products_row.forEach(({ options, ...rest }) =>
  Object.values(options).forEach((b) => result.push({ ...rest, ...b })),
);