您可以使用 object 作为关联数组一次性完成这项工作:
var test_items = [
{ title:'child element 2.2', type:'e', id:6, parent:4 },
{ title:'child element 2.1', type:'e', id:5, parent:4 },
{ title:'container 1', type:'c', id:1, parent:0 },
{ title:'container 2', type:'c', id:4, parent:0 },
{ title:'child element 1.1', type:'e', id:2, parent:1 },
{ title:'child element 1.2', type:'e', id:3, parent:1 },
{ title:'element without parent A', type:'e', id:8, parent:0 },
{ title:'element without parent B', type:'e', id:7, parent:0 }
];
function itemsToTree2( items ) {
var tree2 = {};
for( var i=0; i<items.length; ++i ) {
var item = items[i];
if( item.type=='c' || item.parent==0 ) {
if( !tree2[item.id] ) {
var parent = { id:item.id, parent:0, children:[] };
tree2[item.id] = parent;
}
tree2[item.id].title = item.title;
tree2[item.id].type = 'c';
} else {
if( !tree2[item.parent] ) {
var parent = { id:item.parent, parent:0, children:[] };
tree2[item.parent] = parent;
}
tree2[item.parent].children.push(item);
}
}
return tree2;
}
var test_tree2 = itemsToTree2(test_items);
console.log(test_tree2);
不确定它是否会明显更快......如果您知道每个容器都会出现在输入数据中的元素之前 - 上面的代码可以简化:
function itemsToTree2( items ) {
var tree2 = {};
for( var i=0; i<items.length; ++i ) {
var item = items[i];
if( item.type=='c' || item.parent==0 ) {
item.children = [];
tree2[item.id] = item;
} else {
tree2[item.parent].children.push(item);
}
}
return tree2;
}
如果您需要按字母顺序对树(按标题)进行级别(通常是这种情况),您将需要额外的处理:
function sortTree2( tree2, comparator ) {
var tree2array = [];
for( var id in tree2 )
tree2array.push( tree2[id] );
tree2array.sort(comparator);
for( var i=0; i<tree2array.length; ++i )
tree2array[i].children.sort(comparator);
return tree2array;
}
var sorted_tree2 = sortTree2( test_tree2, function(a,b) {
return a.title > b.title;
});
console.log(sorted_tree2);
也存在深度超过 2 层的树的通用解决方案。它使用类似的方法,并不比这复杂多少。