Карта списка объектов с вложенным массивом объектов - PullRequest
0 голосов
/ 28 августа 2018

У меня есть эта структура данных, которую я хочу отобразить в однострочном режиме 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 голосов
/ 28 августа 2018

Ну, это не одна строка, но это может быть ... если вы удалите все разрывы строк: 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();
0 голосов
/ 28 августа 2018

Не однострочный, но возвращает желаемый результат и использует 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()])
0 голосов
/ 28 августа 2018

Вы были на правильном пути. Вот оно:

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

Используется деструктуризация массива для объединения элементов.

0 голосов
/ 28 августа 2018

Вы можете использовать Array.prototype.reduce для агрегирования ввода по идентификатору и 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);
0 голосов
/ 28 августа 2018

Почти вы можете получить сгруппированные элементы на карте и сопоставить карту с требуемым свойством id и itmes.

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; }
0 голосов
/ 28 августа 2018

Карта не будет хорошим выбором для этого типа результата, карта используется в основном, когда вам нужно изменить и получить ту же структуру. Вы можете использовать уменьшить для этого.

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...