Skip to main content
  1. About
  2. For Teams
Asked
Viewed 90 times
0

Sorry my english is not good, hope everyone understand. I have an array:

var data=[
{
"id": 2,
"parent_id": 1
},
{
"id": 3,
"parent_id": 2
},
{
"id": 7,
"parent_id": 3
},
{
"id": 67,
"parent_id": 1
}
]

And this is what I need the result to look:

[
{
"id": 2,
"parent_id": 1,
"child":[
  {
    "id": 3,
    "parent_id": 2,
    "child":[{
      "id": 7,
      "parent_id": 3
      },
    ]}
  ]},
{
"id": 67,
"parent_id": 1
},]

My idea is: 1 method has 2 parameters of the same array. I use nested loop. If parent_id == id will add the field "child".

const getTree = function(data, maindata){
  const result=data.forEach(item =>{
    const child=maindata.forEach(element =>{
      if(item.id === element.parent_id){
        return true;
      }
      return false
    })
    getTree(child, maindata)
    item.child = child;
  })
  return result;
}
console.log(getTree(data,data))

But it is not working as it should. Hope everybody help please. thanks

3 Answers 3

1

I'm not sure what your original code is supposed to do, but you're not getting any results because data.forEach doesn't return anything. You need to first filter out the objects that are children (which I assume is what your original code was aiming to do) and then afterwards assign all the objects to their parents like this:

var data=[{"id": 2,"parent_id": 1},{"id": 3,"parent_id": 2},{"id": 7,"parent_id": 3},{"id": 67,"parent_id": 1},]

const filterData = function(data) {
  return data.filter(item => {
    let isChild = false;
    data.forEach(parent => {
      if (parent.id == item.parent_id) {
        isChild = true;
        return;
      }
    });
    return !isChild;
  });
}

const getTree = function(data, maindata){
  return data.map(item =>{
    let children = [];
    maindata.forEach(child => {
      if (item.id == child.parent_id) {
        children.push(child);
      }
    });
    if (children.length > 0) {
      item.child = getTree(children, maindata);
    }
    return item;
  });
}
console.log(getTree(filterData(data),data));

Sign up to request clarification or add additional context in comments.

Comments

0

Another way:

var data=[{"id": 2,"parent_id": 1},{"id": 3,"parent_id": 2},{"id": 7,"parent_id": 3},{"id": 67,"parent_id": 1},]

data.sort(byHierarchy);
var dest = [], idx = {};
for (var i of data) {
  if (i.parent_id === 1) {
    dest.push(i);
} else {
    let j = idx[i.parent_id];
    if (j.child) j.child.push(i);
    else j.child = [i];
  }
  idx[i.id] = i;
}

function byHierarchy(a, b) {
  if (a.parent_id === b.parent_id) return a.id - b.id;
  return a.parent_id - b.parent_id;
}

console.log(JSON.stringify(dest, null, 2).replace(/([{[\]}])[\s\n]+([{[\]}])/g, '$1$2'));

2 Comments

Thanks fo answer. But This is sample data, so your solution is not correct.
You should give us better data in case you think there is any error ;-) Results are same if I do not count syntaxt errors in your suggested result.
0

I think this is the cleanest way to do it

const data=[{"id": 2,"parent_id": 1},{"id": 3,"parent_id": 2},{"id": 7,"parent_id": 3},{"id": 67,"parent_id": 1},]

let makeTree = (data, parent) => {
    let node = []
    data
        .filter(d => d.parent_id == parent)
        .forEach(d => {
            d.child = makeTree(data, d.id)
            node.push(d)
        })
    return node
}
console.log(JSON.stringify(makeTree(data,1),null,2))

Comments

Your Answer

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.