You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LINQ搜索层级数据的问题及关联节点信息获取需求

解决LINQ层级结构搜索的两个问题

1. 覆盖所有根节点的任意深度搜索

你之前的代码只遍历第一个根节点,核心问题是没处理所有根节点的全层级遍历。直接写一个通用的扁平化扩展方法,把整个层级结构(所有根节点+所有深度的子节点)转成扁平集合即可:

先定义你的层级数据类(假设结构如下):

public class HierarchyNode
{
    public string CodeValue { get; set; }
    public string Name { get; set; }
    public List<HierarchyNode> Children { get; set; } = new List<HierarchyNode>();
}

然后写一个迭代式的扩展方法(避免递归深度过大导致的栈溢出):

public static IEnumerable<HierarchyNode> FlattenAll(this IEnumerable<HierarchyNode> rootNodes)
{
    var stack = new Stack<HierarchyNode>(rootNodes);
    while (stack.Count > 0)
    {
        var node = stack.Pop();
        yield return node;
        // 倒序压栈,保证子节点顺序和原结构一致
        foreach (var child in node.Children.Reverse())
        {
            stack.Push(child);
        }
    }
}

使用时直接传入所有根节点集合,就能拿到所有层级的节点:

var allNodes = rootNodes.FlattenAll();
// 搜索目标节点,比如筛选CodeValue为"target"的节点
var targetNodes = allNodes.Where(n => n.CodeValue == "target").ToList();

2. 扁平化后获取父/兄弟节点的关联信息

只扁平化节点本身会丢失层级关系,所以扁平化时要保留父节点引用。可以用匿名类型或自定义类存储节点与父节点的关联:

方式1:用匿名类型存储父子关系

public static IEnumerable<(HierarchyNode Node, HierarchyNode Parent)> FlattenWithParent(this IEnumerable<HierarchyNode> rootNodes)
{
    var stack = new Stack<(HierarchyNode Node, HierarchyNode Parent)>();
    // 根节点的父节点为null
    foreach (var root in rootNodes)
    {
        stack.Push((root, null));
    }

    while (stack.Count > 0)
    {
        var (node, parent) = stack.Pop();
        yield return (node, parent);
        foreach (var child in node.Children.Reverse())
        {
            stack.Push((child, node));
        }
    }
}

使用示例:

var nodesWithParent = rootNodes.FlattenWithParent().ToList();

// 找到目标节点后,直接获取父节点的CodeValue
var target = nodesWithParent.FirstOrDefault(x => x.Node.CodeValue == "target");
if (target != null)
{
    var parentCode = target.Parent?.CodeValue; // 根节点的父节点为null
    Console.WriteLine($"父节点CodeValue:{parentCode}");

    // 获取兄弟节点的CodeValue(父节点的所有子节点,排除当前节点)
    var siblingCodes = target.Parent?.Children.Where(c => c != target.Node).Select(c => c.CodeValue).ToList();
    if (siblingCodes != null)
    {
        Console.WriteLine("兄弟节点CodeValue:" + string.Join(", ", siblingCodes));
    }
}

方式2:自定义类存储更丰富的层级信息

如果需要层级深度、完整路径等额外信息,可以定义专用类:

public class NodeWithHierarchy
{
    public HierarchyNode Node { get; set; }
    public HierarchyNode Parent { get; set; }
    public int Depth { get; set; }
    public string FullPath { get; set; }
}

public static IEnumerable<NodeWithHierarchy> FlattenWithHierarchy(this IEnumerable<HierarchyNode> rootNodes)
{
    var stack = new Stack<NodeWithHierarchy>();
    foreach (var root in rootNodes)
    {
        stack.Push(new NodeWithHierarchy
        {
            Node = root,
            Parent = null,
            Depth = 0,
            FullPath = root.CodeValue
        });
    }

    while (stack.Count > 0)
    {
        var item = stack.Pop();
        yield return item;
        foreach (var child in item.Node.Children.Reverse())
        {
            stack.Push(new NodeWithHierarchy
            {
                Node = child,
                Parent = item.Node,
                Depth = item.Depth + 1,
                FullPath = $"{item.FullPath}/{child.CodeValue}"
            });
        }
    }
}

这种方式不仅能获取父节点信息,还能拿到层级深度、完整路径等数据,适配更多业务场景。


内容的提问来源于stack exchange,提问作者InquisitiveLad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 16:45:44