В моем случае ни один из предложенных ответов не работал.
Вот что сработало для меня:
Второй шаг был важен, по-видимому, так как он не работал без него.
Вы можете уменьшить массив до одного значения ( Карта ), а затем распределить значения этой карты как новый массив:
[117 ]const busses = [
{ busId: '234', minToStop: 40, timeToStop: 1390 },
{ busId: '123', minToStop: 16, timeToStop: 957 },
{ busId: '123', minToStop: 23, timeToStop: 1490 },
{ busId: '234', minToStop: 17, timeToStop: 957 },
{ busId: '123', minToStop: 40, timeToStop: 1390 },
{ busId: '123', minToStop: 30, timeToStop: 1390 },
{ busId: '234', minToStop: 1, timeToStop: 1490 },
];
console.log([
...busses
.sort((a, b) => a.minToStop - b.minToStop)
.reduce((result, bus) => {
const parentBus = result.get(bus.busId);
const current = parentBus || {
...bus,
laterBusses: [],
};
if (!!parentBus) {
//only add to laterbusses if it's not the first bus found
current.laterBusses.push(bus);
}
return result.set(current.busId, current);
}, new Map())
.values(),
]);
Это решение будет сначала сортировать шины по minToStop
, а затем по busId
. Затем он перебирает массив buses
и условно помещает шину на верхний уровень массива final
или вкладывает, как вы просили.
const buses = [
{ busId: "234", minToStop: 40, timeToStop: 1390 },
{ busId: "123", minToStop: 16, timeToStop: 957 },
{ busId: "123", minToStop: 23, timeToStop: 1490 },
{ busId: "234", minToStop: 17, timeToStop: 957 },
{ busId: "123", minToStop: 30, timeToStop: 1390 },
{ busId: "234", minToStop: 1, timeToStop: 1490 }
];
buses.sort((a,b) => a.minToStop - b.minToStop);
buses.sort((a,b) => a.busId > b.busId);
let formatted = [];
buses.forEach(bus => {
if (
formatted.length > 0 &&
formatted[formatted.length - 1].busId === bus.busId
) {
formatted[formatted.length - 1].laterBuses.push(bus);
} else {
bus.laterBuses = [];
formatted.push(bus);
}
});
console.log(formatted);