使用LINQ展平树结构
假设有一个由MyNode
类表示的分层树数据结构,其中每个节点都有一个父节点、一个子节点集合和一个组标识符,本文探讨如何使用LINQ将其转换为扁平列表。
挑战
目标是获得所有MyNode
对象的列表,包括父节点和子节点,作为一个单一的扁平列表。但是,只有group == 1
的节点应该包含在结果列表中。
解决方案
为了实现这种展平,可以使用以下LINQ表达式:
<code class="language-csharp">IEnumerable<MyNode> Flatten(IEnumerable<MyNode> e) => e.SelectMany(c => Flatten(c.Elements)).Concat(e);</code>
此表达式递归遍历树结构,将其展平为单个列表。它选择给定节点的所有子节点,并对其递归调用Flatten
,生成子节点序列。然后将此序列与当前节点连接起来,生成合并列表。
按组过滤
一旦树被展平,可以使用Where(...)
方法过滤列表,只选择group == 1
的节点。
<code class="language-csharp">var result = flattenedNodes.Where(n => n.group == 1);</code>
附加样式增强
为了提高可读性,Flatten
方法可以定义为静态类中的扩展函数:
<code class="language-csharp">public static IEnumerable<MyNode> Flatten(this IEnumerable<MyNode> e) => e.SelectMany(c => c.Elements.Flatten()).Concat(e);</code>
泛型实现
为了使展平过程通用化,可以创建一个泛型扩展方法,它接受一个树结构和一个函数,以从节点生成后代:
<code class="language-csharp">public static IEnumerable<T> Flatten<T>( this IEnumerable<T> e, Func<T, IEnumerable<T>> f ) => e.SelectMany(c => f(c).Flatten(f)).Concat(e);</code>
这种方法允许展平任何分层数据结构,前提是定义了一个函数来从每个元素检索后代节点。
要使用此泛型实现,只需调用Flatten
方法并提供相应的函数来提取后代即可:
<code class="language-csharp">var res = tree.Flatten(node => node.Elements);</code>
以上是如何使用LINQ将层次树结构变成平坦的列表?的详细内容。更多信息请关注PHP中文网其他相关文章!