[英]How to get depth of hierarchical data with linq query?
我有一個像這樣的分層數據列表:
var list = new List<Data>(){some data...}
class Data
{
public int number;
public List<Data> info;
}
注意:樹的葉子中的數據 - > info = null
例:
numbers是Data類的number property
--1
--11
--2
--21
--22
--23
--24
--3
--31
--32
--321
--322
--4
--41
--42
如何通過linq查詢(非遞歸方法或for循環)知道樹的最大深度到數據列表?
在此示例中,321,322的最大級別為3
謝謝。
LINQ和SQL在平面數據結構上運行; 它們不是為遞歸數據結構而設計的。
有了LINQ to Entities,我相信你運氣不好。 將子樹的深度存儲在每個節點中,並在插入/刪除節點時以遞歸方式更新它。
使用LINQ to Objects,您可以定義一個遞歸擴展方法,該方法返回樹中的所有路徑並獲取最長路徑的長度:
var result = root.Paths().Max(path => path.Length);
哪里
public static IEnumerable<Data[]> Paths(this Data data)
{
return Paths(data, new[] { data });
}
private static IEnumerable<Data[]> Paths(Data data, Data[] path)
{
return new[] { path }.Concat((data.info ?? Enumerable.Empty<Data>())
.SelectMany(child => Paths(child, path.Concat(new[] { child }).ToArray())));
}
所有Linq運算符都以某種方式使用循環,因此如果需求不是循環,則無法使用linq求解。
沒有遞歸就有可能。 你只需要一個堆棧。 就像是
public static IEnumerable<Tuple<int, T>> FlattenWithDepth<T>(T root, Func<T, IEnumerable<T>> children) {
var stack = new Stack<Tuple<int, T>>();
stack.Push(Tuple.Create(1, root));
while (stack.Count > 0) {
var node = stack.Pop();
foreach (var child in children(node.Item2)) {
stack.Push(Tuple.Create(node.Item1+1, child));
}
yield return node;
}
}
那么您的linq查詢將是
FlattenWithDepth(root, x => x.info ?? Enumerable.Empty<Data>()).Max(x => x.Item1);
(抱歉,沒有可用於驗證的編譯器)
**編輯。 剛看到你有多個根**
list.SelectMany(y => FlattenWithDepth(y, x => x.info ?? Enumerable.Empty<Data>()))
.Max(x => x.Item1)
以下將有效:
internal static class ListDataExtension
{
public static int MaxDepthOfTree(this List<Data> dataList)
{
return dataList.Max(data => data.MaxDepthOfTree);
}
}
internal class Data
{
public int number;
public List<Data> info;
public int MaxDepthOfTree
{
get
{
return GetDepth(1);
}
}
int GetDepth(int depth)
{
if (info == null)
return depth;
var maxChild = info.Max(x => x.GetDepth(depth));
return maxChild + 1;
}
}
然后打電話:
var maxDepth = list.MaxDepthOfTree();
如果你應該在DB中使用它,我建議在你的數據庫中添加額外的列來保存樹的深度,有一些深度變化的情況:
要查找深度,只需運行查詢以查找最大深度值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.