javascript转换成父子数组

时间:2019-06-18 10:01:00

标签: javascript arrays object

任何人都可以帮助转换以下父子对象列表:

我下面有对象数组,需要将其转换为父子顺序。对象中的每个“成员”属性中可能包含1个或n个对象。在“成员”数组中,第一个对象是第二个对象的父对象,第二个对象是第三个对象的父对象。

所以在第一个会员中  “视频”是“西方”的父级,“西方”是“印度”的父级,依此类推。

我试图一遍一遍地遍历元素,但无法达到预期的结果。

任何有关逻辑或代码的帮助将非常有帮助。

输入:

[
  {
    "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"
      }
    ]
  }
]

预期输出:

[
  {
    "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": []
          }
        ]
      }
    ]
  }
]

```

3 个答案:

答案 0 :(得分:2)

这花了太长时间。但它适用于更大的数据集。注意OP,切勿使用此数据结构。曾经这太糟糕了。我失去了许多解决此问题的方法:

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)

答案 1 :(得分:1)

这可能不是解决此问题的最佳方法,并且仅适用于3个级别。

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));

答案 2 :(得分:-1)

我建议使用map + reduce组合:

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);