简体   繁体   中英

javascript convert into parent-child array

Can anyone help converting the following list of parent-child objects:

I have below array of objects, Need to convert it into parent child order. each 'Members' attribute in object may have 1 or n objects inside it. In 'Members' array the 1st object is parent of 2nd one and 2nd is parent of third object.

So in 1st Member 'Video' is parent of 'West' and 'West' is parent of 'India' and so on..

I have tried to loop through the elements one by one but could not reach the desired outcome.

Any help with the logic or code would be really helpful.

Input :

[
  {
    "Members": [
      {
        "Name": "Videos"
      },
      {
        "Name": "West"
      },
      {
        "Name": "India"
      }
    ]
  },
  {
    "Members": [
      {
        "Name": "Machinery"
      },
      {
        "Name": "South"
      },
      {
        "Name": "Australia"
      }
    ]
  },
  {
    "Members": [
      {
        "Name": "Electronics"
      },
      {
        "Name": "Midwest"
      },
      {
        "Name": "Arab"
      }
    ]
  },
  {
    "Members": [
      {
        "Name": "Machinery"
      },
      {
        "Name": "West"
      },
      {
        "Name": "India"
      }
    ]
  },
  {
    "Members": [
      {
        "Name": "Electronics"
      },
      {
        "Name": "NorthEast"
      },
      {
        "Name": "Japan"
      }
    ]
  },
  {
    "Members": [
      {
        "Name": "Videos"
      },
      {
        "Name": "South"
      },
      {
        "Name": "Australia"
      }
    ]
  },
  {
    "Members": [
      {
        "Name": "Videos"
      },
      {
        "Name": "West"
      },
      {
        "Name": "Japan"
      }
    ]
  }
]

Expected Output :

[
  {
    "name": "Videos",
    "children": [
      {
        "name": "West",
        "children": [
          {
            "name": "India",
            "children": []
          },
          {
            "name": "Japan",
            "children": []
          }
        ]
      },
      {
        "name": "South",
        "children": [
          {
            "name": "Australia",
            "children": []
          }
        ]
      }
    ]
  },
  {
    "name": "Machinery",
    "children": [
      {
        "name": "South",
        "children": [
          {
            "name": "Australia",
            "children": []
          }
        ]
      },
      {
        "name": "West",
        "children": [
          {
            "name": "India",
            "children": []
          }
        ]
      }
    ]
  },
  {
    "name": "Electronics",
    "children": [
      {
        "name": "Midwest",
        "children": [
          {
            "name": "Arab",
            "children": []
          }
        ]
      },
      {
        "name": "NorthEast",
        "children": [
          {
            "name": "Japan",
            "children": []
          }
        ]
      }
    ]
  }
]

```

Man this took too long. But it works with larger datasets. Note to OP, never use this data structure. Ever. It's horrible. I lost many braincells making this solution:

 var arr = [ {Members: [{ Name: "Videos" }, { Name: "West" }, { Name: "India" }, {Name: 'Testing'}]}, {Members: [{ Name: "Machinery" }, { Name: "South" }, { Name: "Australia" }]}, {Members: [{ Name: "Electronics" }, { Name: "Midwest" }, { Name: "Arab" }]}, {Members: [{ Name: "Machinery" }, { Name: "West" }, { Name: "India" }]}, {Members: [{ Name: "Electronics" }, { Name: "NorthEast" }, { Name: "Japan" }]}, {Members: [{ Name: "Videos" }, { Name: "South" }, { Name: "Australia" }]}, {Members: [{ Name: "Videos" }, { Name: "West" }, { Name: "Japan" }]} ]; const addRelation = (obj, m, i) => ({...obj, parent: i === 0 ? null : m.slice(0, i).map(el => el.Name).join('.'), level: i, children: []}) const arrayToTree = (arr) => { arr = arr.map(({ Members: m }) => m.map((obj, i) => addRelation(obj, m, i))).reduce((acc, arr) => { arr.map(obj => acc.push(obj)) return acc }, []).sort((a, b) => b.level - a.level) var temp = [...arr].filter((o, index, self) => index === self.findIndex((t) => ( t.Name === o.Name && t.parent === o.parent )) ) arr.forEach(() => { if (temp[0].level === 0) return var parentIndex = temp.findIndex(o => { var str = temp[0].parent var rest = str.substring(0, str.lastIndexOf(".")); var last = str.substring(str.lastIndexOf(".") + 1, str.length); var parents = [rest, last] return parents[0] !== '' ? o.Name === parents[1] && o.parent === parents[0] : o.Name === temp[0].parent }) const { Name, children } = temp[0] temp[parentIndex].children.push({Name, children}) temp.shift() }) return temp.map(({ Name, children }) => ({ Name, children })) } arr = arrayToTree(arr) console.log(arr) 

This might not be the best way to go about this and this only works for 3 levels.

 var data = [ { "Members": [ { "Name": "Videos" }, { "Name": "West" }, { "Name": "India" } ] }, { "Members": [ { "Name": "Machinery" }, { "Name": "South" }, { "Name": "Australia" } ] }, { "Members": [ { "Name": "Electronics" }, { "Name": "Midwest" }, { "Name": "Arab" } ] }, { "Members": [ { "Name": "Machinery" }, { "Name": "West" }, { "Name": "India" } ] }, { "Members": [ { "Name": "Electronics" }, { "Name": "NorthEast" }, { "Name": "Japan" } ] }, { "Members": [ { "Name": "Videos" }, { "Name": "South" }, { "Name": "Australia" } ] }, { "Members": [ { "Name": "Videos" }, { "Name": "West" }, { "Name": "Japan" } ] } ]; function organize(dataBefore){ var dataAfter = []; dataAfter.push({ name: dataBefore[0].Members[0].Name, children: [] }); for(var i = 1; i < dataBefore.length; i++){ if(!doesExist(dataAfter, dataBefore[i].Members[0].Name)){ dataAfter.push({ name: dataBefore[i].Members[0].Name, children: [] }); } } dataAfter[0].children.push({ name: dataBefore[0].Members[1].Name, children: [] }); for(var i = 1; i < dataBefore.length; i++){ for(var j = 0; j < dataAfter.length; j++){ if(dataAfter[j].name == dataBefore[i].Members[0].Name){ if(!doesExist(dataAfter[j].children, dataBefore[i].Members[1].Name)){ dataAfter[j].children.push({ name: dataBefore[i].Members[1].Name, children: [] }); } } } } dataAfter[0].children[0].children.push({ name: dataBefore[0].Members[2].Name, children: [] }); for(var i = 1; i < dataBefore.length; i++){ for(var j = 0; j < dataAfter.length; j++){ if(dataAfter[j].name == dataBefore[i].Members[0].Name){ for(var k = 0; k < dataAfter[j].children.length; k++){ if(dataAfter[j].children[k].name == dataBefore[i].Members[1].Name){ if(!doesExist(dataAfter[j].children[k].children, dataBefore[i].Members[2].Name)){ dataAfter[j].children[k].children.push({ name: dataBefore[i].Members[2].Name, children: [] }); } } } } } } return dataAfter; } function doesExist(checkThisData, searchValue){ for(var i = 0; i < checkThisData.length; i++){ if(searchValue == checkThisData[i].name){ return true; } } return false; } console.log(organize(data)); 

I would advise to use map + reduce combination:

 const data = [{ "Members": [{ "Name": "Videos" }, { "Name": "West" }, { "Name": "India" } ] }, { "Members": [{ "Name": "Machinery" }, { "Name": "South" }, { "Name": "Australia" } ] }, { "Members": [{ "Name": "Electronics" }, { "Name": "Midwest" }, { "Name": "Arab" } ] }, { "Members": [{ "Name": "Machinery" }, { "Name": "West" }, { "Name": "India" } ] }, { "Members": [{ "Name": "Electronics" }, { "Name": "NorthEast" }, { "Name": "Japan" } ] }, { "Members": [{ "Name": "Videos" }, { "Name": "South" }, { "Name": "Australia" } ] }, { "Members": [{ "Name": "Videos" }, { "Name": "West" }, { "Name": "Japan" } ] } ]; const ar = data.map((el, i) => { let a = el['Members'].reduce((acc, member, index) => { if (index === 0) { acc[index] = { name: member.Name, children: [] }; } else { debugger; if (acc[0].children.length === 0) { acc[0].children.push({ name: member.Name, children: [] }); } else { acc[0].children[0].children.push({ name: member.Name, children: [] }); } } return acc; }, []); return a; }); console.log(ar); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM