Given the following array:
const activities = [
{ type: 'car', duration: 60 },
{ type: 'car', duration: 140 },
{ type: 'ferry', duration: 60 },
{ type: 'car', duration: 100 }
];
What would be the best approach to merge
consecutive objects with type: 'car'
while retaining the order of elements? In this example, the desired result would be:
const activities = [
{ type: 'car', duration: 200 }, // merged
{ type: 'ferry', duration: 60 },
{ type: 'car', duration: 100 } // this stays
];
The array is built dynamically and the example is simplified for clarity.
After quite some attemps I've managed to write working code, using a combination of do/while
, findIndex()
, slice()
and reduce()
to populate a new array. The code feels cumbersome and involves many operations, though.
I'm left wondering if there is an easy approach (that I'm not seeing) to solve this problem... any suggestions are welcome!
Use Array.reduce()
to iterate the objects. If the last item in the accumulator has the same type as that of the current item (o
), add the duration to the last item. If not add the current object to the accumulator.
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);