Сгруппировать массив JS

Есть данные формата

const data = [
    {date:'Дата 1', value: 'Событие 1'},
    {date:'Дата 1', value: 'Событие 2'},
    {date:'Дата 2', value: 'Событие 4'}
];

Мне нужно сформировать новый массив так, чтобы результат был

const newData = [
    {date:'Дата 1', value: 'Событие 1 и Событие 2'},
    {date: 'Дата 2', value: 'Событие 4'}
];

Пробовал такой подход

const arr22 = []

data.forEach((element,b) => {
    if(arr22.includes(element['date'])){
        arr22[b]['val'] += element['val'] + 'Add'
    }else{
        arr22.push(element)
    }
})

Ответы (2 шт):

Автор решения: Sergey Glazirin

const data = [{
    date: 'Дата 1',
    value: 'Событие 1'
  },
  {
    date: 'Дата 1',
    value: 'Событие 2'
  },
  {
    date: 'Дата 2',
    value: 'Событие 4'
  }
];


const newData = [...new Set(data.map(element => element.date))].map(item => ({
  date: item,
  value: data.filter(el => el.date === item).map(el => el.value).join(' и ')
}));

console.log(newData);

→ Ссылка
Автор решения: nörbörnën

Используя reduce и Map можно сгруппировать всё за один проход c time complexity O(n):

const data = [
  { date: 'Дата 1', value: 'Событие 1', },
  { date: 'Дата 1', value: 'Событие 2', },
  { date: 'Дата 2', value: 'Событие 4', },
];

const reducedMap = data.reduce((acc, {date, value}) => {
  if (!acc.has(date)) {
    acc.set(date, {date, value});
  } else {
    const item = acc.get(date);
    item.value = `${item.value} и ${value}`;
  }
  return acc;
}, new Map());

const reducedData = Array.from(reducedMap.values());
console.log(reducedData);

→ Ссылка