JS, сортировка и группировка массива объектов по условию

В наличии такой массив объектов:

[
   {id: 1, time: 30000},
   {id: 2, time: 35000},
   {id: 5, time: 39000},
   {id: 8, time: 91000}
]

На выходе должен получиться такой объект:

{
   30000: [1, 2, 5],
   91000: [8]
}

В исходном массиве все объекты сравниваются по полю time, если разница между ними меньше 60.000, то все id подходящих под условие объектов собираются в один массив. А ключом (time) должно быть наименьшее из всех сравниваемых значений.

Я не могу понять как мне получить такой объект, все мои попытки потерпели фиаско.


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

Автор решения: Aziz Umarov

Можно так

let array = [
   {id: 1, time: 30000},
   {id: 2, time: 35000},
   {id: 5, time: 39000},
   {id: 8, time: 91000}
];

let result = array.reduce((acc, item)=> {
   let existing = acc.filter(item2=>Math.abs(item2.time - item.time)<60000)[0];
   if(!existing){
        acc.push({time:item.time, value:[item.id]})
   } else {
        existing.value.push(item.id);
   } return acc;},[])
  .reduce((acc, item)=>(acc[item.time] = item.value, acc),{});

console.log(result);

или поробовать за один редюс

let array = [
   {id: 1, time: 30000},
   {id: 2, time: 35000},
   {id: 5, time: 39000},
   {id: 8, time: 91000}
];

let result = array.reduce((acc, item)=> {
   let key = Object.keys(acc).filter(item2=>Math.abs(item2 - item.time)<60000)[0];
   if(!key){
        acc[item.time] = [item.id]
   } else {
        acc[key].push(item.id);
   } return acc;},{});

console.log(result);

и код покороче

let array = [
   {id: 1, time: 30000},
   {id: 2, time: 35000},
   {id: 5, time: 39000},
   {id: 8, time: 91000}
];

let result = array.reduce((a,i)=>{
   let k = Object.keys(a).filter(i2=>Math.abs(i2-i.time)<60000)[0];
   k?a[k].push(i.id):a[i.time]=[i.id];
   return a;},{});

console.log(result);

→ Ссылка