Javascript 为匹配算法计算通过树的路径
我试图开发一个函数来搜索树结构,并返回通过简单字符串测试(indexOf)的所有节点的完整路径。 我认为我有点接近,因为我可以处理任意深度的N个根节点,只要路径是线性的。当我分支时会出现问题,因为应该发生的是每个分支都会成为一个包含其整个路径的不同数组。但是,发生的情况是,每个分支都被合并到一个公共数组中,该数组表示发生分支的父级的所有子级下面的匹配路径 显示正确结果的简单搜索,数据中没有分支 显示数据中存在分支的错误/合并结果的搜索 在上图中,结果应该包含三个元素,每个元素表示遍历的不同路径(“Z”上的字符串测试匹配)。 [1aa,1a,1],[1aba,1aa,1a,1],[2aa,2a,2] 注释掉数据中的“Zoe”条目,以便在线性测试和分支测试之间切换Javascript 为匹配算法计算通过树的路径,javascript,recursion,Javascript,Recursion,我试图开发一个函数来搜索树结构,并返回通过简单字符串测试(indexOf)的所有节点的完整路径。 我认为我有点接近,因为我可以处理任意深度的N个根节点,只要路径是线性的。当我分支时会出现问题,因为应该发生的是每个分支都会成为一个包含其整个路径的不同数组。但是,发生的情况是,每个分支都被合并到一个公共数组中,该数组表示发生分支的父级的所有子级下面的匹配路径 显示正确结果的简单搜索,数据中没有分支 显示数据中存在分支的错误/合并结果的搜索 在上图中,结果应该包含三个元素,每个元素表示遍历的不同
(函数(){
风险值数据=
[
{“姓名”:“迈克”,“身份证”:“1”,“儿童”:
[
{“姓名”:“吉姆”,“身份证”:“1a”,“儿童”:
[
{“name”:“Zoe”,“id”:“1aa”,“children”:[]},//取消对失败测试的注释
{“姓名”:“嘉莉”,“身份证”:“1ab”,“儿童”:
[
{“name”:“Zane”,“id”:“1aba”,“children”:[]}
]}
]}
]},
{“姓名”:“艾伦”,“身份证”:“2”,“儿童”:
[
{“姓名”:“弗雷德”,“身份证”:“2a”,“儿童”:
[
{“姓名”:“扎克”,“身份证”:“2aa”,“儿童”:
[
{“姓名”:“院长”,“身份证”:“2aaa”,“儿童”:[]}
]}
]}
]}
];
var rFX=功能(val,项目){
var子匹配=[];
子匹配=(item.children.map(函数(子){
返回rFX(val,子项);
}));
子匹配=[].concat.apply([],子匹配);
if(item.name.indexOf(val)>-1 | | subMatches.length>0){
子匹配推送(项目id);
}
返回子匹配;
};
var结果=data.map(函数(项){
返回rFX(“Z”,项目);
});
控制台日志(结果);
})();代码>我放弃了最初的方法,因为在堆栈上返回递归调用时,合并数据的复杂性似乎太难了
相反,我将问题分解为两个函数
GetAllPath:此函数遍历整个结构,计算到叶节点的所有可能路径的数组。此处不执行过滤。每个递归调用都传递一个先前在其路径中处理的节点数组。当函数到达一个没有更多子节点的节点时,它会将最终路径添加到数组中,然后将路径数组放置在所有递归调用都已关闭的主数组上
filterPaths:该函数将从getAllPaths返回的集合中的每个路径(从下到上)一小撮,直到找到匹配项为止,从而为我们留下一个匹配项的路径集合
(函数(){
风险值数据=[{
“姓名”:“迈克”,
“id”:“1”,
“儿童”:[{
“姓名”:“吉姆”,
“id”:“1a”,
“儿童”:[{
“姓名”:“佐伊”,
“id”:“1aa”,
“儿童”:[]
},
{
“姓名”:“嘉莉”,
“id”:“1ab”,
“儿童”:[{
“姓名”:“赞恩”,
“id”:“1aba”,
“儿童”:[]
}]
}
]
}]
}, {
“姓名”:“艾伦”,
“id”:“2”,
“儿童”:[{
“姓名”:“弗雷德”,
“id”:“2a”,
“儿童”:[{
“姓名”:“扎克”,
“id”:“2aa”,
“儿童”:[{
“姓名”:“院长”,
“id”:“2aaa”,
“儿童”:[]
}]
}]
}]
}];
//返回数据中的所有完整路径(到叶节点的路径)
var getAllPath=函数(项){
//所有调用将其完成的路径数组推送到的数组。
var master=[];
//递归调用以跟踪数据中的每条路径。
var rFXi=函数(项,项数组){
itemArray.push(item);//始终推送当前项
//如果我们还有子对象,则递归地处理它们
如果(item.children&&item.children.length>0){
item.children.forEach(函数(子函数){
rFXi(子级,itemArray.slice());
});
}
//否则我们在一个叶节点,所以把完整的路径数组推到主节点上。
否则{
主推(itemArray);
}
};
//启动我们的递归调用
items.forEach(函数(子项){
rFXi(儿童,[]);
});
返回主机;
};
//根据比较器函数测试我们的路径,
//删除端子匹配下的所有路径段
//然后只返回那些剩余的带有
//长度大于零。
var filterPaths=函数(路径、比较器){
forEach(函数(路径){
var匹配=假,
长度=路径长度,
我
对于(i=path.length-1;i>=0&&!matched;i--){
if(比较器(路径[i],“D”)){
匹配=真;
}否则{
//删除不匹配的叶
路径拼接(i,1);
}
}
});//前端
返回路径。过滤器(函数(路径){
返回路径长度>0;
});
};
//检索“树”中叶节点的所有路径
变量路径=GetAllPath(数据);
console.log(路径);
//现在过滤这些路径以获得匹配的段
路径=过滤器路径(路径、函数(项、值){
返回项.name.indexOf(val)>-1;
});
console.log(路径);
})();
重新思考rFX
的返回值应该是什么样子。然后检查递归调用的结果是否正确。现在重新思考,尝试另一种方法,因为我不知道这种方法如何避免合并子树。如何定义“子树”?是路径数组吗?@Bergi,是的。。。最终结果中的每个数组都应该表示一个完整的pat