将数组内部对象内的数组映射到单个数组中

时间:2018-03-25 00:08:56

标签: javascript arrays

我有一个对象数组,其中每个对象都有一个属性,其值是另一个数组,如此

[
  {
    location: 'somewhere',
    location_id: 1,
    parts: [
      {
        part_id: 1,
        description: 'foo',
        qty: 1,
      }
    ]
  }
]

我需要将这些数组映射到像这样的单个数组

[
  {
    part_id: 1,
    description: 'foo',
    qty: 1
  },
  {
    part_id: 2,
    description: 'bar',
    qty: 1
  }
]

我尝试过使用reduce之类的 newArr: arr.reduce((a,b) => a.parts.concat(b.parts))但是得到错误'无法读取未定义的属性concat。'我也尝试将reduce的initialValue参数作为空数组提供但是同样的错误。

作为奖励,我最终需要最终的数组不包含重复的部分:I.e。如果零件位于两个位置,它只会合并数量。

使用es6打开解决方案,但不需要修改原始数组

6 个答案:

答案 0 :(得分:1)

如果您确定要映射数组而不是内部对象:



const input = [
  {
    location: 'somewhere',
    location_id: 1,
    parts: [
      {
        part_id: 1,
        description: 'something'
      }
    ]
  },
  {
    location: 'somewhere2',
    location_id: 22,
    parts: [
      {
        part_id: 2,
        description: 'something'
      }
    ]
  }
];

const mapped = input.map(outerObj => outerObj.parts[0]);
console.log(mapped);




答案 1 :(得分:1)

这会将所有零件对象添加到基础中并删除零件数组。它将修改旧对象。

let arr = [
  {
    location: 'somewhere',
    location_id: 1,
    parts: [
      {
        part_id: 1,
        description: 'something'
      }
    ]
  }
]

arr.map(m => {
  m.parts.forEach(p => Object.assign(m, p))
  delete m.parts;
})

console.log(arr);

答案 2 :(得分:1)

您可以使用array#reduce首先加入每个对象的所有parts数组。然后使用array#reducepart_iddescription上的结果数组中的每个对象进行分组,并为每个唯一对象总结qty。然后从这个对象中获取所有值。



const input = [ { location: 'somewhere', location_id: 1, parts: [ { part_id: 1, description: 'foo', qty: 1 } ] }, { location: 'somewhere2', location_id: 22, parts: [ { part_id: 2, description: 'something', qty: 3 } ] }, { location: 'somewhere2', location_id: 22, parts: [ { part_id: 2, description: 'something', qty: 4 } ] } ],
      result = Object.values(input.reduce((r, {parts}) => r.concat(parts),[])
        .reduce((r,o) => {
          r[`${o.part_id}_${o.description}`] = r[`${o.part_id}_${o.description}`] || {...o, qty: 0};
          r[`${o.part_id}_${o.description}`].qty += o.qty;
          return r;
        },{}));
console.log(result);




答案 3 :(得分:1)

此解决方案使用reduceforEach将子数组中的所有对象合并为Map,其中part_d为关键,qty为合计数量的结果。找到新的part_id后,spreading部件会将新对象创建为新对象,并将qty覆盖为0。

然后通过spreading Map.values()迭代器将地图转换回数组:



const data = [{"location":"somewhere","location_id":1,"parts":[{"part_id":1,"description":"foo","qty":1}]},{"location":"somewhere2","location_id":2,"parts":[{"part_id":1,"description":"foo","qty":3},{"part_id":2,"description":"bar","qty":1}]}];

const result = [...
  data.reduce((r, { parts }) => {
    (parts || []).forEach((o) => {
      r.has(o.part_id) || r.set(o.part_id, { ...o, qty: 0 });

      r.get(o.part_id).qty += o.qty;
    });

    return r;
  }, new Map())
.values()];

console.log(result);




答案 4 :(得分:0)

此问题可能有两种情况:

  1. 每个位置在零件数组下都有单个对象。

    <强>样本

  2. let jsonObj = [
      {
        location: 'somewhere',
        location_id: 1,
        parts: [
          {
            part_id: 1,
            description: 'foo',
            qty: 1,
          }
        ]
      },
      {
        location: 'somewhere',
        location_id: 2,
        parts: [
          {
            part_id: 2,
            description: 'foo',
            qty: 1,
          }
        ]
      }
    ];
    
    let res = jsonObj.map(obj => obj.parts[0]);
    console.log(res);

    1. 单个位置在parts数组下有多个对象。

      <强>样本

    2. let jsonObj = [
        {
          location: 'somewhere',
          location_id: 1,
          parts: [
            {
              part_id: 1,
              description: 'foo',
              qty: 1,
            },
            {
              part_id: 2,
              description: 'foo',
              qty: 1,
            }
          ]
        }
      ];
      
      let res = jsonObj[0].parts;
      console.log(res);

答案 5 :(得分:0)

我也有类似的情况。对我有用的是定义一个新数组,然后从一个双映射函数内部定义array.push(part)

const input = [{
    location: 'somewhere',
    location_id: 1,
    parts: [{
        part_id: 1,
        description: 'something'
      },
      {
        part_id: 2,
        description: 'something'
      }
    ]
  },
  {
    location: 'somewhere2',
    location_id: 22,
    parts: [{
        part_id: 3,
        description: 'something'
      },
      {
        part_id: 4,
        description: 'something'
      }
    ]
  }
];

如果这是您的输入。

var list = []
input.map(item => {
  item.parts.map(part => {
    list.push(part);
  });
});