我正面临一个脑力破坏者(对我来说是体力): 我得到一个带有一个深度数据对象数组的json文件,如下所示:
[
{"id":1, "name":"Sport", "parent_id":0, "children":[]},
{"id":2, "name":"Tennis", "parent_id":4, "children":[]},
{"id":3, "name":"Climbing", "parent_id":5, "children":[]},
{"id":4, "name":"Indoor", "parent_id":1, "children":[]},
{"id":5, "name":"Outdoor", "parent_id":1, "children":[]},
{"id":6, "name":"Bowling", "parent_id":4, "children":[]}
]
如何在树结构中转换它,其中子项放在父项的子数组中?对象并不总是正确的顺序,子进程可以在数组中的父对象之前。 (比如我的例子中的id 2和3)
这就是我最终需要它的方式:
[
{"id":1, "name":"Sport", "parent_id":0, "children":
[
{"id":4, "name":"Indoor", "parent_id":1, "children":
[
{"id":2, "name":"Tennis", "parent_id":4, "children":[]},
{"id":6, "name":"Bowling", "parent_id":4, "children":[]},
]},
{"id":5, "name":"Outdoor", "parent_id":1, "children":
[
{"id":3, "name":"Climbing", "parent_id":5, "children":[]}
]},
]}
]
知道如何实现这个目标吗?
我尝试迭代元素并推送其父元素数组内部,但是当父母被移动时,下一个兄弟再也找不到父母......
答案 0 :(得分:5)
我不确定为什么每个人都如此热衷于编写低效的O 2 算法(嵌套for-loops),但这里有一个O(n log n)时间:
function treeify(nodes) {
var indexed_nodes = {}, tree_roots = [];
for (var i = 0; i < nodes.length; i += 1) {
indexed_nodes[nodes[i].id] = nodes[i];
}
for (var i = 0; i < nodes.length; i += 1) {
var parent_id = nodes[i].parent_id;
if (parent_id === 0) {
tree_roots.push(nodes[i]);
} else {
indexed_nodes[parent_id].children.push(nodes[i]);
}
}
return tree_roots;
}
var nodes = [
{"id":1, "name":"Sport", "parent_id":0, "children":[]},
{"id":2, "name":"Tennis", "parent_id":4, "children":[]},
{"id":3, "name":"Climbing", "parent_id":5, "children":[]},
{"id":4, "name":"Indoor", "parent_id":1, "children":[]},
{"id":5, "name":"Outdoor", "parent_id":1, "children":[]},
{"id":6, "name":"Bowling", "parent_id":4, "children":[]}
];
console.log(JSON.stringify(treeify(nodes), undefined, "\t"));
答案 1 :(得分:1)
var arr = [
{"id":1, "name":"Sport", "parent_id":0, "children":[]},
{"id":2, "name":"Tennis", "parent_id":4, "children":[]},
{"id":3, "name":"Climbing", "parent_id":5, "children":[]},
{"id":4, "name":"Indoor", "parent_id":1, "children":[]},
{"id":5, "name":"Outdoor", "parent_id":1, "children":[]},
{"id":6, "name":"Bowling", "parent_id":4, "children":[]}
]
var i = 0, len = arr.length, item, parent, id, key, treeArr = {};
for (; i < len; i++) {
item = arr[i];
parent = item.parent_id;
id = item.id;
if (treeArr[id] == undefined) {
treeArr[id] = item;
} else if (typeof treeArr[id] == 'object') {
for (key in item) {
if (key == 'children') continue;
treeArr[id][key] = item[key];
}
}
if (typeof treeArr[parent] != 'object') {
treeArr[parent] = { children: [] };
}
treeArr[parent].children.push(treeArr[id]);
}
console.log(treeArr[0]);
答案 2 :(得分:0)
试试这个
for (var i = 0; i < a.length; i++) {
for (var j = 0; j < a.length; j++) {
if(a[j].id == a[i].parent_id){
a[i].children.push(a[j])
}
}
}
答案 3 :(得分:0)
函数重新排序会将数组转换为层次结构。它返回具有parent_id === 0的对象作为根对象。 see this fiddle
var src =
[
{"id":1, "name":"Sport", "parent_id":0, "children":[]},
{"id":2, "name":"Tennis", "parent_id":4, "children":[]},
{"id":3, "name":"Climbing", "parent_id":5, "children":[]},
{"id":4, "name":"Indoor", "parent_id":1, "children":[]},
{"id":5, "name":"Outdoor", "parent_id":1, "children":[]},
{"id":6, "name":"Bowling", "parent_id":4, "children":[]}
];
function reorder(orig)
{
var cnt,id, pid, root, fcnt;
for(cnt = 0; cnt < orig.length; cnt = cnt + 1) {
pid = orig[cnt].parent_id;
id = orig[cnt].id;
if (pid === 0) {
root = orig[cnt]
}
// loop until cnt, then skip that index
for (fcnt=0;fcnt<cnt;fcnt=fcnt+1){
if (orig[fcnt].parent_id === id) {
orig[cnt].children.push(orig[fcnt]);
}
}
// loop from cnt + 1 till end of array
for (fcnt=cnt+1;fcnt<orig.length;fcnt=fcnt+1){
if (orig[fcnt].parent_id === id) {
orig[cnt].children.push(orig[fcnt]);
}
}
}
return root;
}
var dest = reorder(src);
console.log(JSON.stringify(dest));
答案 4 :(得分:0)
使用新数组存储结果..
var ret = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i].parent_id == 0) {
ret.push(arr[i]);
continue;
}
for (var j = 0; j < arr.length; j++) {
if (arr[i].parent_id == arr[j].id) {
arr[j].children.push(arr[i]);
break;
}
}
}