var list = [{
'orderSeries': 26342,
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'orderSeries': 26342,
'make': 'audi',
'model': 'rs5',
'year': '2013'
}, {
'orderSeries': null,
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'orderSeries': null,
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'orderSeries': null,
'make': 'kia',
'model': 'optima',
'year': '2012'
}];
Is it possible to group the first 2 objects in this array because the orderSeries value is the same, and the rest of the objects to not be grouped by orderSeries property because the value for those is null?
and to get a format of the array like this when its grouped:
var list = [{
'orderSeries': 26342,
'make': 'audi',
cars: [
{ 'model': 'r8', 'year': '2012'},
{'model': 'rs5', 'year': '2013'}
]
},
{
'orderSeries': null,
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'orderSeries': null,
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'orderSeries': null,
'make': 'kia',
'model': 'optima',
'year': '2012'
}]
CodePudding user response:
What about this?
var list = [{
'orderSeries': 26342,
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'orderSeries': 26342,
'make': 'audi',
'model': 'rs5',
'year': '2013'
}, {
'orderSeries': null,
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'orderSeries': null,
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'orderSeries': null,
'make': 'kia',
'model': 'optima',
'year': '2012'
}];
const groupedList = [];
list.forEach(item => {
if (!item.orderSeries) {
groupedList.push(item);
} else {
const existingGroup = groupedList.find(i => i.orderSeries === item.orderSeries);
if (existingGroup) {
existingGroup.cars.push({ model: item.model, year: item.year });
} else {
groupedList.push({
orderSeries: item.orderSeries,
make: item.make,
cars: [
{ model: item.model, year: item.year }
]
});
}
}
});
console.log(groupedList);
CodePudding user response:
- Using
Array#reduce
, iterate overlist
while updating two arrays, one for orders withorderSeries
and another without it - Using
Array#reduce
again, iterate over the first list withorderSeries
while updating aMap
to group the items by theorderSeries
- The resulting list will include the grouped list and the ones without
orderSeries
const list = [ { 'orderSeries': 26342, 'make': 'audi', 'model': 'r8', 'year': '2012' }, { 'orderSeries': 26342, 'make': 'audi', 'model': 'rs5', 'year': '2013' }, { 'orderSeries': null, 'make': 'ford', 'model': 'mustang', 'year': '2012' }, { 'orderSeries': null, 'make': 'ford', 'model': 'fusion', 'year': '2015' }, { 'orderSeries': null, 'make': 'kia', 'model': 'optima', 'year': '2012' }];
const [ordersWithSeries, ordersWithoutSeries] = list.reduce(([a, b], order) =>
order.orderSeries ? [[...a, order], b] : [a, [...b, order]]
, [[], []]);
const groupedOrdersBySeries = [...
ordersWithSeries.reduce((orderSeriesMap, { orderSeries, make, model, year }) => {
const order = orderSeriesMap.get(orderSeries);
if(!order) {
orderSeriesMap.set(orderSeries, { orderSeries, make, cars: [{ model, year }] });
} else {
order.cars.push({ model, year });
}
return orderSeriesMap;
}, new Map)
.values()
];
const res = [...groupedOrdersBySeries, ...ordersWithoutSeries ];
console.log(res);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
I would simply manipulate original data one by one using for loop.
const list = [{
orderSeries: 26342,
make: "audi",
model: "r8",
year: "2012"
},
{
orderSeries: 26342,
make: "audi",
model: "rs5",
year: "2013"
},
{
orderSeries: null,
make: "ford",
model: "mustang",
year: "2012"
},
{
orderSeries: null,
make: "ford",
model: "fusion",
year: "2015"
},
{
orderSeries: null,
make: "kia",
model: "optima",
year: "2012"
}
];
let mergeIndexes = [];
let newList = [];
const placeholder = {
orderSeries: null,
make: "",
cars: []
};
for (let i = 0; i <= list.length - 1; i ) {
// continue if current index is already merge with the previous
if (mergeIndexes.includes(i.toString())) continue;
const item = list[i];
const filter = list.filter((i) => i.orderSeries === item.orderSeries);
if (filter.length && Boolean(item.orderSeries)) {
placeholder.orderSeries = filter[0].orderSeries;
placeholder.make = filter[0].make;
placeholder.cars = filter.reduce(
(prev, curr) => [...prev, {
model: curr.model,
year: curr.year
}], []
);
newList = [...newList, placeholder];
// to keep track of the indexes that are already merge
mergeIndexes = [...mergeIndexes, ...Object.keys(filter)];
} else {
newList = [...newList, item];
}
}
console.log(newList);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>