Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

169
Views
How to group an array of objects by key in this case

Does anyone know of a way to group an array of objects by an object key then create a new array of objects based on the grouping? For example, I have an array of menu objects:

let menus = [
    {id: 1, parentId: 0, text: 'Home'},
    {id: 2, parentId: 0, text: 'About'},
    {id: 3, parentId: 0, text: 'Product'},
    {id: 4, parentId: 3, text: 'Product Category 1'},
    {id: 5, parentId: 3, text: 'Product Category 2'},
    {id: 6, parentId: 3, text: 'Product Category 3'},
    {id: 7, parentId: 0, text: 'Contact'},
    {id: 8, parentId: 7, text: 'Contact child 1'},
    {id: 9, parentId: 0, text: 'Blog'},
]

I want to make a new array of menu objects that's grouped by parentId

[
    {id: 1, parentId: 0, text: 'Home'},
    {id: 2, parentId: 0, text: 'About'},
    {id: 3, parentId: 0, text: 'Product', child: [
        {id: 4, parentId: 3, text: 'Product Category 1'},
        {id: 5, parentId: 3, text: 'Product Category 2'},
        {id: 6, parentId: 3, text: 'Product Category 3'},
    ]},
    {id: 7, parentId: 0, text: 'Contact', child: [
        {id: 8, parentId: 7, text: 'Contact child 1'},
    ]},
    {id: 9, parentId: 0, text: 'Blog'},
]

UPDATE this is my code:

let newListMenu = []
menus.forEach(it => {
   let childrenData = []
   if (it.parentId&& it.parentId!== 0) {
       let parent = menus.find(_it => _it.Id == it.parentId)
       childrenData.push(it)
       parent.child= child
    } else {
       newListMenu.push(it)
    }
 })
about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

You can achieve this using Array.reduce easily.

Here I have demonstrated a case where you have multi level of nesting. That is you can have child nodes inside a child node. If you have only one level of nesting you can use the commented loginc in the code for finding the parent node.

See code comments for implementation details.

const menus = [{ id: 1, parentId: 0, text: 'Home' }, { id: 2, parentId: 0, text: 'About' }, { id: 3, parentId: 0, text: 'Product' }, { id: 4, parentId: 3, text: 'Product Category 1' }, { id: 5, parentId: 3, text: 'Product Category 2' }, { id: 6, parentId: 3, text: 'Product Category 3' }, { id: 7, parentId: 0, text: 'Contact' }, { id: 8, parentId: 7, text: 'Contact child 1' }, { id: 9, parentId: 0, text: 'Blog' }, { id: 10, parentId: 6, text: 'New Node' }];

const findParentNode = (nodes, child) => {
  let parent;
  // Loop through input array
  // Check if the id of any node is matching with the parent id 
  nodes.forEach((item) => {
    if(item.id === child.parentId) {
      parent = item;
      return; // Break loop
    } else if(item.child && item.child.length) {
      // Check the child nodes
      const newParent = findParentNode(item.child, child);
      parent = newParent ? newParent : parent;
      return; // Break loop
    }
  });
  return parent;
}
const groupedMenu = menus.reduce((acc, curr) => {
  // Use this if you have one level of nesting.
  // const parentNode = acc.find(node => node.id === curr.parentId);
  
  // Find the parent node from the accumulator list and the current node
  const parentNode = findParentNode(acc, curr);
  
  // If parent node is found, push the current node to the child node of parent
  // Else push the node to accumulator
  if (parentNode) {
    parentNode.child ? parentNode.child.push(curr) : parentNode.child = [curr] 
  } else {
    acc.push(curr);
  }
  return acc;
}, []);

console.log(groupedMenu);

about 4 years ago · Juan Pablo Isaza Report

0

You can use reduce.

const menus = [
  {id: 1, parentId: 0, text: 'Home'},
  {id: 2, parentId: 0, text: 'About'},
  {id: 3, parentId: 0, text: 'Product'},
  {id: 4, parentId: 3, text: 'Product Category 1'},
  {id: 5, parentId: 3, text: 'Product Category 2'},
  {id: 6, parentId: 3, text: 'Product Category 3'},
  {id: 7, parentId: 0, text: 'Contact'},
  {id: 8, parentId: 7, text: 'Contact child 1'},
  {id: 9, parentId: 0, text: 'Blog'},
];
const nested = menus.reduce((acc, item) => {
  // if parentId is 0, add to acc.
  if (item.parentId === 0) {
    return [
      ...acc,
      item,
    ];
  }

  // else find the parent.
  const parentIndex = acc.findIndex(parent => parent.id === item.parentId);
  const parent = acc[parentIndex];
  const children = parent.children ?? [];

  // update the array item at index.
  return Object.assign(
    [],
    acc,
    {
      [parentIndex]: {
        ...parent,
        children: [...children, item], // add the item as a child.
      },
    },
  );
}, []);

console.log(nested);

EDIT: This will only add the children on a single level. For multiple levels of nesting, you should probably do recursion.

about 4 years ago · Juan Pablo Isaza Report

0

let menus = [
    {id: 1, parentId: 0, text: 'Home'},
    {id: 2, parentId: 0, text: 'About'},
    {id: 3, parentId: 0, text: 'Product'},
    {id: 4, parentId: 3, text: 'Product Category 1'},
    {id: 5, parentId: 3, text: 'Product Category 2'},
    {id: 6, parentId: 3, text: 'Product Category 3'},
    {id: 7, parentId: 0, text: 'Contact'},
    {id: 8, parentId: 7, text: 'Contact child 1'},
    {id: 9, parentId: 0, text: 'Blog'},
]

function getUniqGroupList(data, val) {
    var grouped = [];
    data.forEach(function (a) {
      if (!this[a[val]]) {
        this[a[val]] = {
          parentId: a[val],
          items: []
        };
        grouped.push(this[a[val]]);
      }
      this[a[val]].items.push(a);
    }, Object.create(null));

    return grouped;
}
  
var d = getUniqGroupList(menus,'parentId');
console.log(d);
  

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!