JOCKEY
JOCKEY

Reputation: 53

Nested child in javascript

I have an array like this.

var main_childs = [
    {child_name: 1, childs:[2,4]},
    {child_name: 2, childs:[3]},
    {child_name: 3, childs:""},
    {child_name: 4, childs:""}
]

main_child.childname 1 have childs 2 and 4 that exist in main_childs so if main_childs.child_name is a child of one of the child name it will output like this

final_childs = [
    {
        1: {
            name: 1,
            childs: [
                {
                    name: 2, 
                    childs: [
                            {
                                name: 3, 
                                childs: []
                            },

                        ],
                    name: 4,
                    childs:[]

                }
            ]
        },

    }
]

I'm trying to solve it using this function

  function recursive(main_childs){
   main_childs.forEach(i=> {
       if(i.childs.length>0){
         recursive(i.childs)
       }
  })

Any help will be appreciated

Upvotes: 0

Views: 745

Answers (2)

CimaW
CimaW

Reputation: 29

EDIT: I have add a function that search all parents

Try this:

var main_childs = [
    {child_name: 1, childs:[2,4]},
    {child_name: 2, childs:[3]},
    {child_name: 3, childs:""},
    {child_name: 4, childs:""},
    {child_name: 5, childs:[]}
]

var final_childs=[]

var parents=getParents();

parents.forEach(child=>{
    var parent={name:child.child_name,childs:[]};
  recursiveFunc(parent,child.childs);
  final_childs.push({});
  final_childs[final_childs.length-1][parent.name]=parent;
}

)
console.log(final_childs);

function recursiveFunc(parent,childNames){
  if(childNames=="")
    return
  childNames.forEach(childName=>{
    var child={name:childName,childs:[]}
    var main_child=main_childs.find(el=>el.child_name==childName);
    recursiveFunc(child,main_child.childs)
    parent.childs.push(child)
  })
}


function getParents(){
  let childs=[];
  let parents=[];
  main_childs.forEach(child=>childs.push(child.childs));
  childs=childs.flat(2);
  main_childs.forEach(child=>{
    let name=childs.find(el=>child.child_name==el);
    if(name==null){
      parents.push(child);
    }
  });
  return parents; 
}

Upvotes: 1

R Nair
R Nair

Reputation: 116

Assuming 1 is not always root but other elements can also be root and elements can be out of order as well added extra element

{ child_name: 5, childs: [2] }

Wrote it hastily so ignore function naming, output looks weird but if you tidy it with tabs its the same below code does not handle cyclic dependencies

   var main_childs = [{
    child_name: 1,
    childs: [2, 4]
  },
  {
    child_name: 2,
    childs: [3]
  },
  {
    child_name: 3,
    childs: ""
  },
  {
    child_name: 4,
    childs: ""
  },
  {
    child_name: 5,
    childs: [2]
  }
]

//get all roots

const getRoots = () => {

  let allChilds = main_childs.map(x => {
    if (!x.childs) {
      x.childs = []
    }
    return [...x.childs]
  }).flat()

  let allRoots = main_childs.filter(x => !allChilds.find(y => x.child_name == y)


  )

  return allRoots


}

//recursive call
const transform = (obj) => {
  let result = {}
  result.name = obj.child_name
  result.childs = []
  if (obj.childs) {
    obj.childs.forEach(x => {
      let n = main_childs.find(y => y.child_name == x)
      if (n) {
        result.childs.push(transform(n))
      }
    })

  }
  return result
}
//creation of new structure
const createNewStructure = () => {
  let roots = getRoots()
  let result = []

  roots.forEach(x => {
    let n = {}
    n[x.child_name] = transform(x)
    result.push(n)
  })

  return result
}


console.log(createNewStructure())


//output
/* [{
  1: {
    childs: [{
  childs: [{
  childs: [],
  name: 3
}],
  name: 2
}, {
  childs: [],
  name: 4
}],
    name: 1
  }
}, {
  5: {
    childs: [{
  childs: [{
  childs: [],
  name: 3
}],
  name: 2
}],
    name: 5
  }
}] */

Upvotes: 1

Related Questions