今天在做一个组织结构图时,图是用一个树来表示的,有唯一的根节点以及若干个子节点,二话不说我瞬间就写出来了这个结构,我的定义如下:
var data = {
id: 1,
name: "根节点",
children:[{
id: 2,
name: "节点1",
children: [{
id: 3,
name: "节点3"
},{
id: 4,
name: "节点4"
}]
}]
};
它的需求是:已知id属性的值,要查找其所在的对象。我花了一些时间写了一个递归遍历,代码是这样的:
function recursion(data, current){
for(var prop in data){
if(prop == "id" && data[prop] == current){
return data;
}else if(prop == "children" && data[prop].length > 0){
data[prop].forEach(function(currentValue, index, arr){
return arguments.callee(currentValue, current);
});
}
}
}
本以为这是我很得意的代码,结果却是意想不到,
哈哈哈,懵圈儿,吓得我赶紧关了,这不是无限循环嘛,我的computer哟,仔细一看并打断点排查竟然是循环里执行循环和递归,不是无限循环才怪。然后仔细观察了一下data,发现少了[],这样里([])外({})的结构就不一样了,于是就稍微更改了一下data与递归函数,如下:
var data = [{
id: 1,
name: "根节点",
children:[{
id: 2,
name: "节点1",
children: [{
id: 3,
name: "节点3"
},{
id: 4,
name: "节点4"
}]
}]
}];
function recursion(data, current){
var result = null;
if(!data){
// return; 中断执行
return;
}
for(var i in data){
var item = data[i];
if(item.id == current){
result = item;
break;
}else if(item.children && item.children.length > 0){
result = recursion(item.children, current);
}
}
return result;
}
var r = recursion(data, 3);
console.log(r);
这就可以了。像这种细小的问题可能没那么容易发现,只能怪自己太菜了。若是有不对的地方,欢迎大家指正!
2019-05-31更新
上面代码有一点问题,如果是data是下面的结构:(为了标注所以使用的是图片)
也就是data的元素长度大于1并且children的长度均不为0的时候,当找到所在对象时循环会继续下去,导致result的值被覆盖,所以更新代码如下:
如此即可。