Home > Blockchain >  How could I get the output like objects of array within a key of another objects of array
How could I get the output like objects of array within a key of another objects of array

Time:06-24

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
}

  • Related