用对象子数组映射对象列表

时间:2018-08-28 13:10:37

标签: javascript ecmascript-6

我想以es6单线方式映射此数据结构:

const vehicles = [
  {
    id: 'vehicle1',
    items: [
      {
        id: 'contract1'
        name: 'Contract 1',
      },
    ],
  },
  {
    id: 'vehicle1',
    items: [
      {
        id: 'contract2'
        name: 'Contract 2',
      },
    ],
  },
  {
    id: 'vehicle2',
    items: [
      {
        id: 'contract3'
        name: 'Contract 3',
      },
    ],
  },
  {
    id: 'vehicle2',
    items: [
      {
        id: 'contract4'
        name: 'Contract 4',
      },
    ],
  },
]

我想将其收集在这样的列表中:

const result = [
  {
    id: 'vehicle1',
    items: [
      {
        id: 'contract1'
        name: 'Contract 1',
      },
      {
        id: 'contract2'
        name: 'Contract 2',
      },
    ],
  },
  {
    id: 'vehicle2',
    items: [
      {
        id: 'contract3'
        name: 'Contract 3',
      },
      {
        id: 'contract4'
        name: 'Contract 4',
      },
    ],
  },
]

因此,列表中的车辆是唯一的,项目在一个列表中。

我尝试过此方法,但它只收集列表中的车辆:

const res = vehicles.reduce((acc, vehicle) => acc.set(vehicle.id, vehicle), new Map())

我该如何以“ ES6方法”进行操作?

6 个答案:

答案 0 :(得分:1)

对于这种类型的结果,Map不是一个好的选择,Map主要用于必须修改并获得相同结构的情况。您可以为此使用reduce。

var data = [{
        id: 'vehicle1',
        items: [{
            id: 'contract1',
            name: 'Contract 1'
        }]
    },
    {
        id: 'vehicle1',
        items: [{
            id: 'contract2',
            name: 'Contract 2'
        }]
    },
    {
        id: 'vehicle2',
        items: [{
            id: 'contract3',
            name: 'Contract 3'
        }]
    },
    {
        id: 'vehicle2',
        items: [{
            id: 'contract4',
            name: 'Contract 4'
        }]
    }
];

var result = {};

data.forEach(val => {
    if (result[val.id])
        result[val.id].items = result[val.id].items.concat(val.items);
    else
        result[val.id] = val
});

result = Object.values(result);

console.log(result);

答案 1 :(得分:0)

您几乎可以在地图中获得分组的项目,并使用所需的iditmes属性映射该地图。

const
    vehicles = [{ id: 'vehicle1', items: [{ id: 'contract1', name: 'Contract 1', }] }, { id: 'vehicle1', items: [{ id: 'contract2', name: 'Contract 2', }] }, { id: 'vehicle2', items: [{ id: 'contract3', name: 'Contract 3', }] }, { id: 'vehicle2', items: [{ id: 'contract4', name: 'Contract 4' }] }],
    result = Array.from(
        vehicles.reduce((acc, { id, items }) =>
            acc.set(id,  (acc.get(id) || []).concat(items)), new Map()),
        ([id, items]) => ({ id, items })
    );

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

答案 2 :(得分:0)

您可以使用Array.prototype.reduce通过id聚合输入,并使用Object.keys以所需的格式获取输出

const vehicles=[{id:'vehicle1',items:[{id:'contract1',name:'Contract 1'}]},{id:'vehicle1',items:[{id:'contract2',name:'Contract 2'}]},{id:'vehicle2',items:[{id:'contract3',name:'Contract 3'}]},{id:'vehicle2',items:[{id:'contract4',name:'Contract 4'}]}];

const grouped = vehicles.reduce((all, {id, items}) => {

  if (!all.hasOwnProperty(id)) all[id] = { id, items: [] };

  all[id].items.push(...items);

  return all;

}, {});

const result = Object.keys(grouped).map(k => grouped[k]);

console.log(result);

答案 3 :(得分:0)

您在正确的道路上。在这里:

const res = vehicles.reduce((m,v)=>m.set(v.id, [...v.items, ...(m.get(v.id)||[])]), new Map)

这使用数组分解来合并项目。

答案 4 :(得分:0)

不是单线的,但它返回期望的结果并使用ES6 Map

const data = [{"id":"vehicle1","items":[{"id":"contract1","name":"Contract 1"}]},{"id":"vehicle1","items":[{"id":"contract2","name":"Contract 2"}]},{"id":"vehicle2","items":[{"id":"contract3","name":"Contract 3"}]},{"id":"vehicle2","items":[{"id":"contract4","name":"Contract 4"}]}]

const res = data.reduce((acc, {id, items}) => {
  if(!acc.get(id)) acc.set(id, {id, items});
  else acc.get(id).items.push(...items);
  return acc;
}, new Map())

console.log([...res.values()])

答案 5 :(得分:0)

好吧,它不是一个衬里,而是...如果删除所有换行符:D

const convert = () => {
    const vMap = vehicles.reduce((acc, vehicle) => {
        if (acc[vehicle.id]) {
            acc[vehicle.id].items.push(...vehicle.items);
        } else {
            acc[vehicle.id] = vehicle;
        }
        return acc;
    }, {});
    return Object.keys(vMap).map(k => vMap[k]);
};

convert();