Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从祖先数据构建嵌套列表?_Javascript_Algorithm_Tree - Fatal编程技术网

Javascript 从祖先数据构建嵌套列表?

Javascript 从祖先数据构建嵌套列表?,javascript,algorithm,tree,Javascript,Algorithm,Tree,鉴于结构: { id: 'id-1', name: 'name1', ancestors: [] },{ id: 'id-2', name: 'name2', ancestors: [] },{ id: 'id-3', name: 'name3', ancestors: ['id-1'] },{ id: 'id-4', name: 'name4', ancestors: ['id-3', 'id-1'

鉴于结构:

{
    id: 'id-1',
    name: 'name1',
    ancestors: []
},{
    id: 'id-2',
    name: 'name2',
    ancestors: []
},{
    id: 'id-3',
    name: 'name3',
    ancestors: ['id-1']
},{
    id: 'id-4',
    name: 'name4',
    ancestors: ['id-3', 'id-1']
}
  • 假设它们没有以任何有意义的方式进行排序
  • “祖先”字段是一个数组,显示到顶层的路径
构建嵌套列表(ul)最有效的方法是什么


我的第一个想法是递归方法,但这似乎很麻烦,因为它会重复搜索整个列表。因为这是一个在浏览器中运行的javascript解决方案,可能会有问题。

您可以构建一个树,然后呈现一个嵌套列表

函数getTree(数据){
var o={};
data.forEach(函数(a){
var parent=a.a[0];
if(o[a.id]&&o[a.id].儿童){
a、 children=o[a.id]。children;
}
o[a.id]=a;
o[父]=o[父]|{};
o[parent]。children=o[parent]。children | |[];
o[parent].children.push(a);
});
返回未定义的子对象;
}
函数构建列表(树、目标){
var ul=document.createElement('ul');
tree.forEach(o=>{
var li=document.createElement('li');
li.appendChild(document.createTextNode(o.name));
构建列表(o.children | |[],li);
ul.儿童(li);
});
目标儿童(ul);
}
var data=[{id:'id-1',name:'name1',祖先:[]},{id:'id-2',name:'name2',祖先:[]},{id:'id-3',name:'name3',祖先:['id-1']},{id:'id-4',name:'name4',祖先:['id-3',id-1']},
tree=getTree(数据);
控制台日志(树);

构建列表(树、文档、正文)构建地图以加快查找速度:

 const byId = new Map(array.map(el => ([el.id, el]));
创建嵌套树非常简单,我们只需检查节点是否没有祖先,然后检查其是否为根元素,否则将其添加为父节点的子节点:

 const root = [];

 for(const obj of array) {
   if(obj.ancestors.length) {
     const parent = byId.get(obj.ancestors[0]);
     if(parent.children) {
       parent.children.push(obj);
     } else {
       parent.children = [obj];
     }
   } else {
    root.push(obj);
   }
 }
因此,现在
root
包含一个嵌套树,您可以使用递归方法遍历它:

 function traverse(elements) {
    for(const el of elements) {
      // Render ...
      traverse(el.children || []);
    }
 }

 traverse(root);

构建树后端怎么样?一个元素怎么可能有多个祖先?@Cid nodejs@乔纳斯。无论是哪种语言,如果是客户机-服务器应用程序,他都可以构建树服务器端。我们是否可以假设
祖先
数组中的字符串将是现有对象的ID?例如,是否存在对象不存在的字符串id?另外,如何读取
祖先
数组?您能发布问题中提供的示例的预期输出吗?因此,如果我阅读正确,这将只需要一个对象循环,但需要大量的空间,因为每个项目都存在o多次。所以它的计算复杂度很低,但空间复杂度很高?不,一个项目只存在一次。参考文献经常被存储。如果您查看
o
,那么您会看到所有的父节点和节点都包含嵌套的子节点,这些子节点是对单个对象的引用。