【问题标题】:javascript convert into parent-child arrayjavascript转换成父子数组
【发布时间】:2019-06-18 10:01:00
【问题描述】:

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

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

所以在第一个成员中 'Video' 是'West' 的父级,'West' 是'India' 的父级,依此类推..

我试图逐个循环遍历元素,但无法达到预期的结果。

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

输入:

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

```

【问题讨论】:

  • 你以前问过这个吗?? ,我猜。这样的问题需要你的努力,这有助于我们给你一个更好的答案
  • @Shubh 是的,here

标签: javascript arrays object


【解决方案1】:

伙计,这花了太长时间。但它适用于更大的数据集。注意 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)

【讨论】:

  • 大家好,我们又见面了。 :D。你的答案比我的要好,所以不要以错误的方式理解它,但它不会重现所需的输出。
  • @Andam 我刚刚解决了这个问题:)
  • 它确实有效,但它的结构与他的预期结果不同
  • @Andam 你能指出我哪里出错了,我可以解决它
  • 你没有出错,但他的结果是这样的
【解决方案2】:

这可能不是解决此问题的最佳方法,并且仅适用于 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));

【讨论】:

  • 这太复杂了:p
  • @Adnam - 感谢您的代码,它非常适合第 3 级。您能否以任何方式提供帮助,使其不限于仅 3 级。感谢您的努力
  • 是的,我相信我可以。我会尽力回复你
  • 我想不出解决方案,哈哈。数据结构太可怕了:p +1,做得很好。不过我会继续尝试;)
  • @Kobe 是的,我同意。挑战是这里有趣的部分。关于结果,我认为您在开始时有一个额外的节点。您有两个视频 > 答案中有西节点。据我所知。
【解决方案3】:

我建议使用 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);

【讨论】:

  • 您的答案(如 kobe answer)不会重现与他的结果相同的结果。他的结果是这样的视频 > 西部 > 印度,日本,但您的答案是视频 > 西部 > 印度,视频 > 西部 > 日本
猜你喜欢
  • 1970-01-01
  • 2013-08-06
  • 2013-03-25
  • 2018-03-12
  • 2019-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
相关资源
最近更新 更多