Group Objects By Multiple Properties And Merge Array Property
In the example I use a each to go thru select fields and create an array of data, I need to group 2 properties year and cabin also the property months is an array that I would like
Solution 1:
This is a fairly standard group by
situation. The snippet below uses reduce()
to refactor your array, but you could place the logic directly in your function as it is: http://jsfiddle.net/83st9wgh/
const input = [{ "year": "2021", "cabin": "1", "months": ["1", "2"] }, { "year": "2021", "cabin": "1", "months": ["4"] }, { "year": "2021", "cabin": "2", "months": ["1", "2"] }, { "year": "2022", "cabin": "1", "months": ["1", "2"] }, { "year": "2022", "cabin": "1", "months": ["4"] }, { "year": "2022", "cabin": "2", "months": ["1", "2"] }];
const result = input.reduce((acc, { year, cabin, months }) => {
const yearArray = (acc[year] ??= []);
let cIndex = yearArray.findIndex(o => o.cabin === cabin);
if (cIndex === -1) {
cIndex = yearArray.push({ cabin, months: [] }) - 1;
}
const monthsArray = yearArray[cIndex].months;
yearArray[cIndex].months = [...newSet(monthsArray.concat(months))];
return acc;
}, {});
console.log(JSON.stringify(result, null, 2));
Solution 2:
So, you're midway to the solution.
from what you have I wrote a grouping function:
constaddUnique=(arr1,arr2)=>{
arr2.forEach(item=>arr1.includes(item) || arr1.push(item))
return arr1;
}
const grouped= obj.reduce((groups,item)=>{
const yearItems=(groups[item.year]||[])
const cabinItem=yearItems.find(({cabin})=>cabin===item.cabin)
const newCabinItem=cabinItem||{cabin:item.cabin};
newCabinItem.months=addUnique(newCabinItem.months||[],item.months);
return {
...groups,
[item.year]: cabinItem
? yearItems.map(yearItem =>
yearItem.cabin === item.cabin
? newCabinItem
: yearItem)
: yearItems.concat([newCabinItem])
}
},{})
you can see it working here: http://jsfiddle.net/9huwkz5L/
Post a Comment for "Group Objects By Multiple Properties And Merge Array Property"