提问人:Doe 提问时间:12/19/2017 最后编辑:CœurDoe 更新时间:12/1/2018 访问量:270
JavaScript 递归查找节点返回 null
JavaScript recursion find node return null
问:
如何获取匹配节点? 尽管显示匹配节点的警报,但我总是得到 null 返回。
必须有一个递归的保证。
我只想为ID找到相应的节点元素。 这甚至可以通过jQuery为JSON对象提供吗?
function getNode(processingNode, searchNodeId) {
if(processingNode.tags == searchNodeId) {
alert("match!");
return processingNode;
}
else {
var result = null;
for(var i = 0; i < processingNode.nodes.length; i++) {
result = getNode(processingNode.nodes[i], searchNodeId);
}
return result;
}
}
var nodes = [{
"tags": "1",
"text": "BG",
"nodes": [{
"tags": "11",
"text": "DLT",
"nodes": []
}, {
"tags": "12",
"text": "HBM",
"nodes": []
}, {
"tags": "13",
"text": "MBM",
"nodes": []
}, {
"tags": "14",
"text": "RT",
"nodes": [{
"tags": "141",
"text": "FSP",
"nodes": []
}, {
"tags": "142",
"text": "HHR",
"nodes": []
}, {
"tags": "143",
"text": "KHR",
"nodes": []
}, {
"tags": "144",
"text": "KM",
"nodes": []
}, {
"tags": "145",
"text": "Sauger",
"nodes": []
}, {
"tags": "146",
"text": "SM",
"nodes": []
}]
}, {
"tags": "2",
"text": "ST",
"nodes": []
}, {
"tags": "3",
"text": "WHT",
"nodes": []
}, {
"tags": "4",
"text": "ZDLT",
"nodes": []
}, {
"tags": "5",
"text": "ZHBM",
"nodes": []
}, {
"tags": "6",
"text": "ZMM",
"nodes": []
}, {
"tags": "7",
"text": "ZRT",
"nodes": []
}, {
"tags": "8",
"text": "ZST",
"nodes": []
}, {
"tags": "9",
"text": "ZHT",
"nodes": []
}]}
]
$(function() {
var matchingNode = getNode(nodes[0], 142);
alert(matchingNode);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
答:
0赞
ibrahim mahrir
12/19/2017
#1
解释:
即使在找到匹配项后,您的循环也会继续循环,因此,如果其他元素(匹配元素之后的元素)与给定的 ID 不匹配,则该元素将被覆盖。for
result
null
例如,如果在第 5次迭代中我们得到了一个结果,那么我们应该停止循环并返回。相反,您的代码会继续查找,因此,如果最后一次迭代不匹配,将被分配值(在第 5次迭代时覆盖前一个值)。结论:只有当数组的最后一项与 ID 匹配时,您的代码才有效(在这种情况下,循环无论如何都会停止)。result
null
建议的修复方法:
将循环更改为如下所示:
var result = null;
for(var i = 0; i < processingNode.nodes.length; i++) {
result = getNode(processingNode.nodes[i], searchNodeId);
if(result) { // if we got a result
return result; // then return immediately and stop looping
}
}
return result; // keep this in case we don't find anything (or remove it as undefined will be returned implicitly), or change to simply 'return null;'
工作实例:
function getNode(processingNode, searchNodeId) {
if(processingNode.tags == searchNodeId) {
alert("match!");
return processingNode;
}
else {
var result = null;
for(var i = 0; i < processingNode.nodes.length; i++) {
result = getNode(processingNode.nodes[i], searchNodeId);
if(result) return result;
}
return result;
}
}
var nodes = [{
"tags": "1",
"text": "BG",
"nodes": [{
"tags": "11",
"text": "DLT",
"nodes": []
}, {
"tags": "12",
"text": "HBM",
"nodes": []
}, {
"tags": "13",
"text": "MBM",
"nodes": []
}, {
"tags": "14",
"text": "RT",
"nodes": [{
"tags": "141",
"text": "FSP",
"nodes": []
}, {
"tags": "142",
"text": "HHR",
"nodes": []
}, {
"tags": "143",
"text": "KHR",
"nodes": []
}, {
"tags": "144",
"text": "KM",
"nodes": []
}, {
"tags": "145",
"text": "Sauger",
"nodes": []
}, {
"tags": "146",
"text": "SM",
"nodes": []
}]
}, {
"tags": "2",
"text": "ST",
"nodes": []
}, {
"tags": "3",
"text": "WHT",
"nodes": []
}, {
"tags": "4",
"text": "ZDLT",
"nodes": []
}, {
"tags": "5",
"text": "ZHBM",
"nodes": []
}, {
"tags": "6",
"text": "ZMM",
"nodes": []
}, {
"tags": "7",
"text": "ZRT",
"nodes": []
}, {
"tags": "8",
"text": "ZST",
"nodes": []
}, {
"tags": "9",
"text": "ZHT",
"nodes": []
}]}
]
$(function() {
var matchingNode = getNode(nodes[0], 142);
alert(matchingNode);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
0赞
Mulan
12/19/2017
#2
正方形 1
首先,没有“JSON 对象”这样的东西——JSON 始终是一个字符串。程序中有一个 JavaScript 对象。像这样手动写出每个节点的数据,使用 JavaScript 对象文字语法有点粗糙,因此我们将从为节点创建一个构造函数开始
// Node :: (String, String, [Node]) -> Node
const Node = (tags, text, nodes = []) =>
({ tags, text, nodes })
现在我们这样写数据
const tree =
Node ("1", "BG",
[ Node ("11", "DLT")
, Node ("12", "HBM")
, Node ("13", "MBM")
// ...
] )
在树中搜索特定节点是一项基本操作,但将我们的搜索限制在特定字段(即)是一个任意限制——让我们使我们的搜索函数通用,以便我们可以搜索我们想要的任何内容tags
// searchTree :: ((Node -> Boolean), Node, Int) -> Node?
const searchTree = (f, node, cursor = 0) =>
cursor === node.nodes.length
? f (node)
? node
: null
: searchTree (f, node.nodes [cursor]) || searchTree (f, node, cursor + 1)
有了通用搜索功能,我们可以轻松实现按标签搜索功能
// getNodeByTags :: (Node, String) -> Node?
const getNodeByTags = (node, tags) =>
searchTree (n => n.tags === tags, node)
这是一个完整的演示,展示了它的全部工作 - 最后一行演示了实现选择的多功能性
const Node = (tags, text, nodes = []) =>
({ tags, text, nodes })
const searchTree = (f, node, cursor = 0) =>
cursor === node.nodes.length
? f (node)
? node
: null
: searchTree (f, node.nodes [cursor]) || searchTree (f, node, cursor + 1)
const getNodeByTags = (node, tags) =>
searchTree (node => node.tags === tags, node)
const tree =
Node ("0", "ROOT",
[ Node ("1", "BG",
[ Node ("11", "DLT")
, Node ("12", "HBM")
, Node ("13", "MBM")
, Node ("14", "RT",
[ Node ("141", "FSP")
, Node ("142", "HHR")
, Node ("143", "KHR")
, Node ("144", "KM")
, Node ("145", "Sauger")
, Node ("146", "Sm")
] )
] )
, Node ("2", "ST")
, Node ("3", "WHT")
, Node ("4", "ZDLT")
, Node ("5", "ZHBM")
, Node ("6", "ZMM")
] )
console.log (getNodeByTags (tree, "142"))
// { tags: '142', text: 'HHR', nodes: [] }
console.log (getNodeByTags (tree, "999"))
// null
console.log (searchTree (n => n.text === "ZDLT", tree))
// { tags: '4', text: 'ZDLT', nodes: [] }
接下来要读什么:深度优先搜索
评论
id
tagName