使用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中文網其他相關文章!