so I have an Arrray of objects :
[
{
MenuId: 'GM002',
MenuName: 'Profile',
MenuImage: 'CgProfile',
Orderno: '2',
SubMenuId: 'SM001',
SubMenuName: 'Personal Information',
SubMenuImage: 'BsPerson',
SubMenuOrderno: '1',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
},
{
MenuId: 'GM002',
MenuName: 'Profile',
MenuImage: 'CgProfile',
Orderno: '2',
SubMenuId: 'SM002',
SubMenuName: 'Work',
SubMenuImage: 'FcWorkflow',
SubMenuOrderno: '2',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
},
{
MenuId: 'GM002',
MenuName: 'Profile',
MenuImage: 'CgProfile',
Orderno: '2',
SubMenuId: 'SM005',
SubMenuName: 'Document',
SubMenuImage: 'GrDocumentText',
SubMenuOrderno: '5',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
},
{
MenuId: 'GM003',
MenuName: 'Leave Request',
MenuImage: 'FcLeave',
Orderno: '3',
SubMenuId: 'SM006',
SubMenuName: 'Leave Log',
SubMenuImage: 'MdOutlineHolidayVillage',
SubMenuOrderno: '1',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
},
{
MenuId: 'GM003',
MenuName: 'Leave Request',
MenuImage: 'FcLeave',
Orderno: '3',
SubMenuId: 'SM007',
SubMenuName: 'Automation Log',
SubMenuImage: 'TbSettingsAutomation',
SubMenuOrderno: '2',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
},
{
MenuId: 'GM003',
MenuName: 'Leave Request',
MenuImage: 'FcLeave',
Orderno: '3',
SubMenuId: 'SM008',
SubMenuName: 'Rules',
SubMenuImage: 'MdRule',
SubMenuOrderno: '3',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
}
]
but I want it like :
[
{
MenuId: 'GM002',
MenuName: 'Profile',
MenuImage: 'CgProfile',
Orderno: '2',
submenus :
[{
SubMenuId: 'SM001',
SubMenuName: 'Personal Information',
SubMenuImage: 'BsPerson',
SubMenuOrderno: '1',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
},
{
SubMenuId: 'SM002',
SubMenuName: 'Work',
SubMenuImage: 'FcWorkflow',
SubMenuOrderno: '2',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
}]
},
{
MenuId: 'GM003',
MenuName: 'Leave Request',
MenuImage: 'FcLeave',
Orderno: '3',
submenus :
[{
SubMenuId: 'SM006',
SubMenuName: 'Leave Log',
SubMenuImage: 'MdOutlineHolidayVillage',
SubMenuOrderno: '1',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
},
{
SubMenuId: 'SM007',
SubMenuName: 'Automation Log',
SubMenuImage: 'TbSettingsAutomation',
SubMenuOrderno: '2',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
},
{
SubMenuId: 'SM008',
SubMenuName: 'Rules',
SubMenuImage: 'MdRule',
SubMenuOrderno: '3',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
},
{
SubMenuId: 'SM009',
SubMenuName: 'Assets Request',
SubMenuImage: 'MdWebAsset',
SubMenuOrderno: '1',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
}]
}
]
CodePudding user response:
There's endless ways you can do this, below is one approach.
function mergeSubmenus(arr) {
return Object.values(arr.reduce((acc, {MenuId, MenuName, MenuImage, Orderno, ...rest}) => {
const obj = acc[MenuId] ?? { MenuId, MenuName, MenuImage, Orderno, submenus: [] };
obj.submenus.push(rest)
acc[MenuId] = obj;
return acc;
}, {}));
}
CodePudding user response:
You can use the function Array.prototype.reduce
for grouping the objects and then use the function Object.values
for extracting the grouped objects.
const arr = [ { MenuId: 'GM002', MenuName: 'Profile', MenuImage: 'CgProfile', Orderno: '2', SubMenuId: 'SM001', SubMenuName: 'Personal Information', SubMenuImage: 'BsPerson', SubMenuOrderno: '1', SubSubMenuId: null, SubSubMenuName: null, SubSubMenuImage: null, SubSubMenuOrderno: null }, { MenuId: 'GM002', MenuName: 'Profile', MenuImage: 'CgProfile', Orderno: '2', SubMenuId: 'SM002', SubMenuName: 'Work', SubMenuImage: 'FcWorkflow', SubMenuOrderno: '2', SubSubMenuId: null, SubSubMenuName: null, SubSubMenuImage: null, SubSubMenuOrderno: null }, { MenuId: 'GM002', MenuName: 'Profile', MenuImage: 'CgProfile', Orderno: '2', SubMenuId: 'SM005', SubMenuName: 'Document', SubMenuImage: 'GrDocumentText', SubMenuOrderno: '5', SubSubMenuId: null, SubSubMenuName: null, SubSubMenuImage: null, SubSubMenuOrderno: null }, { MenuId: 'GM003', MenuName: 'Leave Request', MenuImage: 'FcLeave', Orderno: '3', SubMenuId: 'SM006', SubMenuName: 'Leave Log', SubMenuImage: 'MdOutlineHolidayVillage', SubMenuOrderno: '1', SubSubMenuId: null, SubSubMenuName: null, SubSubMenuImage: null, SubSubMenuOrderno: null }, { MenuId: 'GM003', MenuName: 'Leave Request', MenuImage: 'FcLeave', Orderno: '3', SubMenuId: 'SM007', SubMenuName: 'Automation Log', SubMenuImage: 'TbSettingsAutomation', SubMenuOrderno: '2', SubSubMenuId: null, SubSubMenuName: null, SubSubMenuImage: null, SubSubMenuOrderno: null }, { MenuId: 'GM003', MenuName: 'Leave Request', MenuImage: 'FcLeave', Orderno: '3', SubMenuId: 'SM008', SubMenuName: 'Rules', SubMenuImage: 'MdRule', SubMenuOrderno: '3', SubSubMenuId: null, SubSubMenuName: null, SubSubMenuImage: null, SubSubMenuOrderno: null }],
result = Object.values(arr.reduce((a, {MenuId, MenuName, MenuImage, Orderno, ...submenus}) => {
(a[MenuId] ?? (a[MenuId] = {MenuId, MenuName, MenuImage, Orderno, submenus: []})).submenus.push(submenus);
return a;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
const data = [{
MenuId: 'GM002',
MenuName: 'Profile',
MenuImage: 'CgProfile',
Orderno: '2',
SubMenuId: 'SM001',
SubMenuName: 'Personal Information',
SubMenuImage: 'BsPerson',
SubMenuOrderno: '1',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
}, {
MenuId: 'GM002',
MenuName: 'Profile',
MenuImage: 'CgProfile',
Orderno: '2',
SubMenuId: 'SM002',
SubMenuName: 'Work',
SubMenuImage: 'FcWorkflow',
SubMenuOrderno: '2',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
}, {
MenuId: 'GM002',
MenuName: 'Profile',
MenuImage: 'CgProfile',
Orderno: '2',
SubMenuId: 'SM005',
SubMenuName: 'Document',
SubMenuImage: 'GrDocumentText',
SubMenuOrderno: '5',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
}, {
MenuId: 'GM003',
MenuName: 'Leave Request',
MenuImage: 'FcLeave',
Orderno: '3',
SubMenuId: 'SM006',
SubMenuName: 'Leave Log',
SubMenuImage: 'MdOutlineHolidayVillage',
SubMenuOrderno: '1',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
}, {
MenuId: 'GM003',
MenuName: 'Leave Request',
MenuImage: 'FcLeave',
Orderno: '3',
SubMenuId: 'SM007',
SubMenuName: 'Automation Log',
SubMenuImage: 'TbSettingsAutomation',
SubMenuOrderno: '2',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
}, {
MenuId: 'GM003',
MenuName: 'Leave Request',
MenuImage: 'FcLeave',
Orderno: '3',
SubMenuId: 'SM008',
SubMenuName: 'Rules',
SubMenuImage: 'MdRule',
SubMenuOrderno: '3',
SubSubMenuId: null,
SubSubMenuName: null,
SubSubMenuImage: null,
SubSubMenuOrderno: null
}]
const result = data.reduce((acc, item) => {
const itemInAcc = acc.find(accItem => accItem.MenuId === item.MenuId)
// the item already exist.
if (itemInAcc) {
itemInAcc.submenus.push({
SubMenuId: item.SubMenuId,
SubMenuName: item.SubMenuName,
SubMenuImage: item.SubMenuImage,
SubMenuOrderno: item.SubMenuOrderno,
SubSubMenuId: item.SubSubMenuId,
SubSubMenuName: item.SubSubMenuName,
SubSubMenuImage: item.SubSubMenuImage,
SubSubMenuOrderno: item.SubSubMenuOrderno
})
} else {
const pushedItem = {
MenuId: item.MenuId,
MenuName: item.MenuName,
MenuImage: item.MenuImage,
Orderno: item.Orderno,
submenus: [{
SubMenuId: item.SubMenuId,
SubMenuName: item.SubMenuName,
SubMenuImage: item.SubMenuImage,
SubMenuOrderno: item.SubMenuOrderno,
SubSubMenuId: item.SubSubMenuId,
SubSubMenuName: item.SubSubMenuName,
SubSubMenuImage: item.SubSubMenuImage,
SubSubMenuOrderno: item.SubSubMenuOrderno
}]
}
acc.push(pushedItem)
}
return acc
}, [])
console.log(result)
CodePudding user response:
If you're using the library underscore you could do something like this (removed properties for sake of example)
_.map(_.groupBy(arr, x => x.MenuId), item => item)
.map(x => {
return {
'MenuId': x[0].MenuId,
'MenuName': x[0].MenuName,
'SubMenu': x.map(y => {
return {
'SubMenuId': y.SubMenuId,
'SubMenuName': y.SubMenuName
}
})
}
});
If not, you can just create a polyfill for groupBy.
Here's a popular one I found, though it could be a bit complex to understand.
CodePudding user response:
You can map through the objects, and slice the two sections. Here's what I mean:
Your array
let menus = [{MenuId: "GM002", ...}, ...];
Map it like this
// First get the subMenus
const subMenus = menus.map(menuItems => {
const subMenus = Object.fromEntries(
Object.entries(menuItems).slice(4)
);
return {...subMenus};
});
// Then the mainMenus section
let item = menus.slice(0,1);
// And finally format it
let mainMenu = {
'MenuId': item[0].MenuId,
'MenuName': item[0].MenuName,
'MenuImage': item[0].MenuImage,
'OrderNo': item[0].Orderno,
'SubMenus': subMenus
}