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

215
Views
Restructure 2 Arrays with Objects as a Nested Array

The goal is to create a new nested array based on 2 flat arrays with objects. If an id from list B matches a refId in list A, the object is added as a child to the object in list A. This creates a new array 2 levels deep as shown in the example.

However in List B, there are objects that have id's that match refId's of their sibling objects. If such is the case the code should find matches and then add them as children of children of parent object. Thus, 3 levels deep. The code should continue to nest until there are no possible matches.

How can the below code be modified to nest any # of levels deep based matching id's and refId's?

// TOP LEVEL
const listA = [ 
  { 
    "id": 23,
    "refId": 23, 
    "name": 'list A #1',
    "isNested": false,
    "depth": 1,
    "children": []
  }, 
  { 
    "id": 25,
    "refId": 25, 
    "name": 'list A #1',
    "isNested": false,
    "depth": 1,
    "children": []
  }
]
// NO HEIRARCHY
const listB = [ 
  { 
    "id": 23,
    "refId": 1234,
    "name": "test 1",
    "isNested": true, 
    "depth": 2, 
    "children": []
  },
  { 
    "id": 25,
    "refId": 1212,
    "name": "test 1",
    "isNested": true, 
    "depth": 2, 
    "children": []
  },
  { 
    "id": 1234,
    "refId": 4324,
    "depth": 3,
    "name": "test 2",
    "isNested": true, 
    "children": []
  }, 
  { 
    "id": 1234,
    "refId": 5678,
    "depth": 3,
    "name": "test 3",
    "isNested": true, 
    "children": []
  }
]

const nestedArr = listA.map(
  ({ id, name, refId, children }) => {
    return {
      id,
      name,
      refId,
      children: listB.filter((b) => {
        return b.id == refId ? b : ''
      }),
    }
  }
)

console.log(nestedArr)

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

If your refs are in order, you can do the following:

  • Concat both arrays
  • For every element,
    • Store the ref in a Map so you can easily access it later
    • If id === refId, push it as a top level ref
    • If not, look up its parent and push it to the children array
const refs = new Map();
const nestedArr = [];

for (const ref of listA.concat(listB)) {
  refs.set(ref.refId, ref);
  
  if (ref.id !== ref.refId) {
    refs.get(ref.id).children.push(ref);
  } else {
    nestedArr.push(ref);
  }
}

console.log(nestedArr)

Here's a runnable snippet:

// TOP LEVEL
const listA = [ 
  { 
    "id": 23,
    "refId": 23, 
    "name": 'list A #1',
    "isNested": false,
    "depth": 1,
    "children": []
  }, 
  { 
    "id": 25,
    "refId": 25, 
    "name": 'list A #1',
    "isNested": false,
    "depth": 1,
    "children": []
  }
]
// NO HEIRARCHY
const listB = [ 
  { 
    "id": 23,
    "refId": 1234,
    "name": "test 1",
    "isNested": true, 
    "depth": 2, 
    "children": []
  },
  { 
    "id": 25,
    "refId": 1212,
    "name": "test 1",
    "isNested": true, 
    "depth": 2, 
    "children": []
  },
  { 
    "id": 1234,
    "refId": 4324,
    "depth": 3,
    "name": "test 2",
    "isNested": true, 
    "children": []
  }, 
  { 
    "id": 1234,
    "refId": 5678,
    "depth": 3,
    "name": "test 3",
    "isNested": true, 
    "children": []
  }
];

const refs = new Map();
const nestedArr = [];

for (const ref of listA.concat(listB)) {
  refs.set(ref.refId, ref);
  
  if (ref.id !== ref.refId) {
    refs.get(ref.id).children.push(ref);
  } else {
    nestedArr.push(ref);
  }
}

console.log(nestedArr)

Note: this mutates the original elements

about 4 years ago · Juan Pablo Isaza Report

0

You could create a Map keyed by all refId and relate to them the corresponding node objects, using the Map constructor. Then iterate the second list to make the attachments.

This mutates the existing children arrays, so listA will have the result:

const listA = [{"id": 23,"refId": 23,"name": 'list A #1',"isNested": false,"depth": 1,"children": []},{"id": 25,"refId": 25,"name": 'list A #1',"isNested": false,"depth": 1,"children": []}];
const listB = [{"id": 23,"refId": 1234,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 25,"refId": 1212,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 1234,"refId": 4324,"depth": 3,"name": "test 2","isNested": true,"children": []},{"id": 1234,"refId": 5678,"depth": 3,"name": "test 3","isNested": true,"children": []}];

const map = new Map(listA.concat(listB).map(node => [node.refId, node]));
for (const {id, refId} of listB) map.get(id).children.push(map.get(refId));

console.log(listA);

If you don't want to mutate the original input, then make sure to create new children arrays:

const listA = [{"id": 23,"refId": 23,"name": 'list A #1',"isNested": false,"depth": 1,"children": []},{"id": 25,"refId": 25,"name": 'list A #1',"isNested": false,"depth": 1,"children": []}];
const listB = [{"id": 23,"refId": 1234,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 25,"refId": 1212,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 1234,"refId": 4324,"depth": 3,"name": "test 2","isNested": true,"children": []},{"id": 1234,"refId": 5678,"depth": 3,"name": "test 3","isNested": true,"children": []}];

const map = new Map(listA.concat(listB).map(node => [node.refId, {...node, children:[]}]));
for (const {id, refId} of listB) map.get(id).children.push(map.get(refId));

const nestedListA = listA.map(({id}) => map.get(id));
console.log(nestedListA);

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!