I have two array of objects that are linked by a parent ID. I am trying to make a list of categories, and in each category is a set of data that corresponds to its respective category. It will be a header (category), then a set of buttons (data). The header data has an ID, the button data has a parentId based on the headers regular ID ex. Category 1 ID = 62, Button 3 parent ID = 62.
I need to create a way to display each category with its respective data.
Category array:
[
{
"categoryName":"Category 1",
"id":62,
"parentId":0,
"txt":"category1"
},
{
"categoryName":"Category 2",
"id":60,
"parentId":0,
"txt":"category2"
},
{
"categoryName":"Category 3",
"id":61,
"parentId":0,
"txt":"category3"
},
{
"categoryName":"Category 4",
"id":59,
"parentId":0,
"txt":"category4"
}
]
Data array:
[
{
"categoryName":"Button 1",
"id":29,
"isChecked":false,
"parentId":60,
"txt":"button1"
},
{
"categoryName":"Button 2",
"id":31,
"isChecked":false,
"parentId":61,
"txt":"button2"
},
{
"categoryName":"Button 3",
"id":35,
"isChecked":false,
"parentId":62,
"txt":"button3"
},
{
"categoryName":"Button 4",
"id":37,
"isChecked":false,
"parentId":62,
"txt":"button4"
},
{
"categoryName":"Button 5",
"id":39,
"isChecked":false,
"parentId":59,
"txt":"button5"
},
{
"categoryName":"Button 6",
"id":41,
"isChecked":false,
"parentId":59,
"txt":"button6"
}
]
Looking for something like this??:
[
{
categoryName: 'Category 1',
id: 62,
parentId: 0,
txt: 'category1',
children: [
{
categoryName: 'Category 1',
id: 62,
parentId: 0,
txt: 'category1',
},
],
},
{
categoryName: 'Category 2',
id: 60,
parentId: 0,
txt: 'category2',
},
{
categoryName: 'Category 3',
id: 61,
parentId: 0,
txt: 'category3',
},
{
categoryName: 'Category 4',
id: 59,
parentId: 0,
txt: 'category4',
},
]
CodePudding user response:
The expected result your provided isn't consistent. But I think I can work with that.
var arr_cat = [{
"categoryName": "Category 1",
"id": 62,
"parentId": 0,
"txt": "category1"
}, {
"categoryName": "Category 2",
"id": 60,
"parentId": 0,
"txt": "category2"
}, {
"categoryName": "Category 3",
"id": 61,
"parentId": 0,
"txt": "category3"
},
{
"categoryName": "Category 4",
"id": 59,
"parentId": 0,
"txt": "category4"
}
];
var arr_data = [{
"categoryName": "Button 1",
"id": 29,
"isChecked": false,
"parentId": 60,
"txt": "button1"
},
{
"categoryName": "Button 2",
"id": 31,
"isChecked": false,
"parentId": 61,
"txt": "button2"
},
{
"categoryName": "Button 3",
"id": 35,
"isChecked": false,
"parentId": 62,
"txt": "button3"
},
{
"categoryName": "Button 4",
"id": 37,
"isChecked": false,
"parentId": 62,
"txt": "button4"
},
{
"categoryName": "Button 5",
"id": 39,
"isChecked": false,
"parentId": 59,
"txt": "button5"
},
{
"categoryName": "Button 6",
"id": 41,
"isChecked": false,
"parentId": 59,
"txt": "button6"
}
]
// first group categories by their id's for easy access.
var obj = arr_cat.reduce(function(agg, item) {
agg[item.id] = item;
return agg;
}, {});
// then assign each data to the relevant sub-object
arr_data.forEach(function(item) {
if (obj[item.parentId]) {
obj[item.parentId].children = obj[item.parentId].children || []
obj[item.parentId].children.push(item);
}
});
// finally get the values array
var final = Object.values(obj);
console.log(final);
.as-console-wrapper {
max-height: 100% !important;
}
CodePudding user response:
// categories is your top level categories object and data is the children you posted
const tree = categories.map(category => {
return {
...category,
children: data.filter(child => child.parentId === category.id)
}
})
What we do here is first loop over the top level categories. We then return the category untouched, but merged with the children
property, which is set to the items in the second dataset which have a matching parentId
to the top level category currently being processed in that first loop.