Конкатенация последовательных (связанных) объектов в массиве с использованием JavaScript - PullRequest
0 голосов
/ 26 декабря 2018

Учитывая следующий массив:

const activities = [
  { type: 'car', duration: 60 },
  { type: 'car', duration: 140 },
  { type: 'ferry', duration: 60 },
  { type: 'car', duration: 100 }
];

Каков наилучший подход для объединения последовательных объектов с type: 'car' при сохранении порядка элементов?В этом примере желаемый результат будет следующим:

const activities = [
  { type: 'car', duration: 200 }, // merged
  { type: 'ferry', duration: 60 },
  { type: 'car', duration: 100 } // this stays
];

Массив создается динамически, а пример упрощен для наглядности.

После нескольких попыток мне удалось написать рабочий кодиспользуя комбинацию do/while, findIndex(), slice() и reduce() для заполнения нового массива.Код кажется громоздким и включает в себя множество операций.

Мне остается только подумать, есть ли простой способ (которого я не вижу) для решения этой проблемы ... любые предложения приветствуются!

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Я уверен, что один из мастеров уточнит это дальше.Но использование набора для сравнения - вот хитрость.ПРИМЕЧАНИЕ: если вы хотите суммировать значения, просто удалите мой массив init и нажмите и перейдите с + =

const activities = [
  { type: 'car', duration: 60 },
  { type: 'car', duration: 140 },
  { type: 'ferry', duration: 60 },
  { type: 'car', duration: 100 }
];


var newSet = new Set();

activities.forEach(activity => {
  if(newSet.has(activity.type) == false) {
    newSet.add(activity.type);
    newSet[activity.type] = [];
  }
  newSet[activity.type].push(activity.duration);
});

console.log(newSet);
0 голосов
/ 26 декабря 2018

Используйте Array.reduce() для итерации объектов.Если последний элемент в аккумуляторе имеет тот же тип, что и текущий элемент (o), добавьте длительность к последнему элементу.Если нет, добавьте текущий объект в аккумулятор.

const activities = [
  { type: 'car', duration: 60 },
  { type: 'car', duration: 140 },
  { type: 'ferry', duration: 60 },
  { type: 'car', duration: 100 }
];

const result = activities.reduce((r, o) => {
  const last = r[r.length - 1];
  
  if(last && last.type === o.type) last.duration += o.duration;
  else r.push({ ...o });
  
  return r;
}, []);

console.log(result);
...