我有一个这样的foreach方法:
TreeNode selectedNode = null;
foreach (TreeNode tn in allNodes)
{
if (selectedNode != null) continue;
var designNodes = tn.Nodes;
foreach (TreeNode item in designNodes)
{
if (item.Tag.ToString().Split('|')[0].Equals(designKey.ToString()))
{
selectedNode = item;
continue;
};
if (selectedNode is null)
{
foreach (TreeNode child in item.Nodes)
{
if (child.Tag != null && child.Tag.ToString().Split('|')[0].Equals(designKey.ToString()))
{
selectedNode = child;
continue;
}
if (selectedNode is null)
{
foreach (TreeNode lastLevel in child.Nodes)
{
if (lastLevel.Tag != null && lastLevel.Tag.ToString().Split('|')[0].Equals(designKey.ToString()))
{
selectedNode = lastLevel;
continue;
}
}
}
}
}
}
}
首先,它迭代进入TreeNode父级,并分配变量selectedNode
,如果未找到结果(selectedNode
仍然为null),则其为父级的子级,如果仍为null,则为其子级的子级
代码可以正常工作,但是很难阅读,有没有实现此迭代的最佳方法?
答案 0 :(得分:0)
听起来您在这里寻找的是宽度优先搜索,您先搜索所有孩子,然后搜索每个孩子的孩子,等等,直到找到匹配项。
>对于这种类型的搜索,我们要使用Queue
,它是“先进先出”(而不是堆栈,后者是“后进先出”)。这样,我们就可以Enqueue
将根TreeNode
项放入队列,然后在循环中一次Dequeue
逐项每个项,检查其是否有效,是否有效,并返回如果不是Enqueue
,那是孩子。这样可以确保我们始终在孩子之前检查父母。
我还通过允许客户端传递用于验证validator
的{{1}}函数来使该方法更加灵活。这样,我们可以重复使用该方法对任意条件进行广度优先搜索(我们只需将接受TreeNode
并返回{{1 }}(如果该节点的验证成功):
TreeNode
在使用中,我们可以将bool
控件的true
属性以及验证函数(在本示例中,我为验证函数传递一个lambda表达式)传递给方法:
private static TreeNode GetFirstMatch(TreeNodeCollection allNodes,
Func<TreeNode, bool> validator)
{
if (allNodes == null) return null;
// Initialize a Queue with all the root nodes
var nodeQueue = new Queue<TreeNode>(allNodes.OfType<TreeNode>());
// Use a queue for a breadth-first search
while (nodeQueue.Any())
{
// Remove the next item
var current = nodeQueue.Dequeue();
// Return it if it passes our validation
if (validator.Invoke(current)) return current;
// Add it's children to the end of the queue
foreach (TreeNode child in current.Nodes)
{
nodeQueue.Enqueue(child);
}
}
// If we didn't find any matches, return null
return null;
}