|
|
@@ -3,6 +3,7 @@ using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
#endif
|
|
|
+
|
|
|
using System.Linq.Expressions;
|
|
|
using Masuit.Tools.Systems;
|
|
|
|
|
|
@@ -20,8 +21,7 @@ public static class TreeExtensions
|
|
|
/// <param name="items"></param>
|
|
|
/// <param name="func"></param>
|
|
|
/// <returns></returns>
|
|
|
- public static IEnumerable<T> Filter<T>(this IEnumerable<T> items, Func<T, bool> func) where T : class, ITreeChildren<T>
|
|
|
- => Flatten(items).Where(func);
|
|
|
+ public static IEnumerable<T> Filter<T>(this IEnumerable<T> items, Func<T, bool> func) where T : class, ITreeChildren<T> => Flatten(items).Where(func);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 过滤
|
|
|
@@ -30,8 +30,7 @@ public static class TreeExtensions
|
|
|
/// <param name="items"></param>
|
|
|
/// <param name="func"></param>
|
|
|
/// <returns></returns>
|
|
|
- public static IEnumerable<Tree<T>> Filter<T>(this IEnumerable<Tree<T>> items, Func<Tree<T>, bool> func) where T : class
|
|
|
- => Flatten(items).Where(func);
|
|
|
+ public static IEnumerable<Tree<T>> Filter<T>(this IEnumerable<Tree<T>> items, Func<Tree<T>, bool> func) where T : class => Flatten(items).Where(func);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 过滤
|
|
|
@@ -40,8 +39,7 @@ public static class TreeExtensions
|
|
|
/// <param name="item"></param>
|
|
|
/// <param name="func"></param>
|
|
|
/// <returns></returns>
|
|
|
- public static IEnumerable<T> Filter<T>(this T item, Func<T, bool> func) where T : class, ITreeChildren<T>
|
|
|
- => Flatten(item).Where(func);
|
|
|
+ public static IEnumerable<T> Filter<T>(this T item, Func<T, bool> func) where T : class, ITreeChildren<T> => Flatten(item).Where(func);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 过滤
|
|
|
@@ -50,8 +48,7 @@ public static class TreeExtensions
|
|
|
/// <param name="item"></param>
|
|
|
/// <param name="func"></param>
|
|
|
/// <returns></returns>
|
|
|
- public static IEnumerable<Tree<T>> Filter<T>(this Tree<T> item, Func<Tree<T>, bool> func) where T : class
|
|
|
- => Flatten(item).Where(func);
|
|
|
+ public static IEnumerable<Tree<T>> Filter<T>(this Tree<T> item, Func<Tree<T>, bool> func) where T : class => Flatten(item).Where(func);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平铺开
|
|
|
@@ -60,9 +57,7 @@ public static class TreeExtensions
|
|
|
/// <param name="items"></param>
|
|
|
/// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
|
|
|
/// <returns></returns>
|
|
|
- public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items, Action<T, T> optionAction = null)
|
|
|
- where T : class, ITreeChildren<T>
|
|
|
- => items.Flatten(i => i.Children ?? [], optionAction);
|
|
|
+ public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items, Action<T, T> optionAction = null) where T : class, ITreeChildren<T> => items.Flatten(i => i.Children ?? [], optionAction);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平铺开
|
|
|
@@ -71,10 +66,7 @@ public static class TreeExtensions
|
|
|
/// <param name="p"></param>
|
|
|
/// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
|
|
|
/// <returns></returns>
|
|
|
- public static IEnumerable<T> Flatten<T>(this T p, Action<T, T> optionAction = null) where T : class, ITreeChildren<T>
|
|
|
- => p != null
|
|
|
- ? Flatten([p], t => t.Children, optionAction)
|
|
|
- : [];
|
|
|
+ public static IEnumerable<T> Flatten<T>(this T p, Action<T, T> optionAction = null) where T : class, ITreeChildren<T> => p != null ? Flatten([p], t => t.Children, optionAction) : [];
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平铺开任意树形结构数据
|
|
|
@@ -124,11 +116,7 @@ public static class TreeExtensions
|
|
|
/// <param name="items"></param>
|
|
|
/// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
|
|
|
/// <returns></returns>
|
|
|
- public static IEnumerable<Tree<T>> Flatten<T>(this IEnumerable<Tree<T>> items,
|
|
|
- Action<Tree<T>, Tree<T>> optionAction = null) where T : class
|
|
|
- => items != null
|
|
|
- ? Flatten(items, t => t.Children, optionAction)
|
|
|
- : [];
|
|
|
+ public static IEnumerable<Tree<T>> Flatten<T>(this IEnumerable<Tree<T>> items, Action<Tree<T>, Tree<T>> optionAction = null) where T : class => items != null ? Flatten(items, t => t.Children, optionAction) : [];
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平铺开
|
|
|
@@ -156,8 +144,7 @@ public static class TreeExtensions
|
|
|
/// <param name="pidSelector"></param>
|
|
|
/// <param name="topValue">根对象parentId的值</param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, string>> idSelector, Expression<Func<T, string>> pidSelector, string topValue = null) where T : ITreeParent<T>, ITreeChildren<T>
|
|
|
- => ToTree<T, string>(source, idSelector, pidSelector, topValue);
|
|
|
+ public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, string>> idSelector, Expression<Func<T, string>> pidSelector, string topValue = null) where T : ITreeParent<T>, ITreeChildren<T> => ToTree<T, string>(source, idSelector, pidSelector, topValue);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平行集合转换成树形结构
|
|
|
@@ -168,8 +155,7 @@ public static class TreeExtensions
|
|
|
/// <param name="pidSelector"></param>
|
|
|
/// <param name="topValue">根对象parentId的值</param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, int>> idSelector, Expression<Func<T, int>> pidSelector, int topValue = 0) where T : ITreeParent<T>, ITreeChildren<T>
|
|
|
- => ToTree<T, int>(source, idSelector, pidSelector, topValue);
|
|
|
+ public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, int>> idSelector, Expression<Func<T, int>> pidSelector, int topValue = 0) where T : ITreeParent<T>, ITreeChildren<T> => ToTree<T, int>(source, idSelector, pidSelector, topValue);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平行集合转换成树形结构
|
|
|
@@ -180,8 +166,7 @@ public static class TreeExtensions
|
|
|
/// <param name="pidSelector"></param>
|
|
|
/// <param name="topValue">根对象parentId的值</param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, long>> idSelector, Expression<Func<T, long>> pidSelector, long topValue = 0) where T : ITreeParent<T>, ITreeChildren<T>
|
|
|
- =>ToTree<T, long>(source, idSelector, pidSelector, topValue);
|
|
|
+ public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, long>> idSelector, Expression<Func<T, long>> pidSelector, long topValue = 0) where T : ITreeParent<T>, ITreeChildren<T> => ToTree<T, long>(source, idSelector, pidSelector, topValue);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平行集合转换成树形结构
|
|
|
@@ -192,8 +177,7 @@ public static class TreeExtensions
|
|
|
/// <param name="pidSelector"></param>
|
|
|
/// <param name="topValue">根对象parentId的值</param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, Guid>> idSelector, Expression<Func<T, Guid>> pidSelector, Guid topValue = default) where T : ITreeParent<T>, ITreeChildren<T>
|
|
|
- =>ToTree<T, Guid>(source, idSelector, pidSelector, topValue);
|
|
|
+ public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, Guid>> idSelector, Expression<Func<T, Guid>> pidSelector, Guid topValue = default) where T : ITreeParent<T>, ITreeChildren<T> => ToTree<T, Guid>(source, idSelector, pidSelector, topValue);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平行集合转换成树形结构
|
|
|
@@ -205,10 +189,7 @@ public static class TreeExtensions
|
|
|
/// <param name="pidSelector"></param>
|
|
|
/// <param name="topValue">根对象parentId的值</param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, Expression<Func<T, TKey>> idSelector, Expression<Func<T, TKey>> pidSelector, TKey topValue = default) where T : ITreeParent<T>, ITreeChildren<T> where TKey : IComparable
|
|
|
- => idSelector.Body.ToString() != pidSelector.Body.ToString()
|
|
|
- ? BuildTree(source.Enumerable2NonNullList(), idSelector.Compile(), pidSelector.Compile(), topValue).ToList()
|
|
|
- : throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
|
|
|
+ public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, Expression<Func<T, TKey>> idSelector, Expression<Func<T, TKey>> pidSelector, TKey topValue = default) where T : ITreeParent<T>, ITreeChildren<T> where TKey : IComparable => idSelector.Body.ToString() != pidSelector.Body.ToString() ? BuildTree(source.Enumerable2NonNullList(), idSelector.Compile(), pidSelector.Compile(), topValue).ToList() : throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平行集合转换成树形结构
|
|
|
@@ -216,8 +197,7 @@ public static class TreeExtensions
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
/// <param name="source"></param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, int>
|
|
|
- =>ToTree<T, int>(source);
|
|
|
+ public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, int> => ToTree<T, int>(source);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平行集合转换成树形结构
|
|
|
@@ -227,8 +207,7 @@ public static class TreeExtensions
|
|
|
/// <param name="source"></param>
|
|
|
/// <param name="topValue"></param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, TKey? topValue = null) where T : class, ITreeEntity<T, TKey> where TKey : struct, IComparable
|
|
|
- => BuildTree(source.Enumerable2NonNullList(), topValue).ToList();
|
|
|
+ public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, TKey? topValue = null) where T : class, ITreeEntity<T, TKey> where TKey : struct, IComparable => BuildTree(source.Enumerable2NonNullList(), topValue).ToList();
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平行集合转换成树形结构
|
|
|
@@ -240,10 +219,7 @@ public static class TreeExtensions
|
|
|
/// <param name="pidSelector"></param>
|
|
|
/// <param name="topValue">根对象parentId的值</param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, Expression<Func<T, TKey>> idSelector, Expression<Func<T, TKey?>> pidSelector, TKey? topValue = null) where T : ITreeChildren<T> where TKey : struct
|
|
|
- => idSelector.Body.ToString() != pidSelector.Body.ToString()
|
|
|
- ? BuildTree(source.Enumerable2NonNullList(), idSelector.Compile(), pidSelector.Compile(), topValue).ToList()
|
|
|
- : throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
|
|
|
+ public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, Expression<Func<T, TKey>> idSelector, Expression<Func<T, TKey?>> pidSelector, TKey? topValue = null) where T : ITreeChildren<T> where TKey : struct => idSelector.Body.ToString() != pidSelector.Body.ToString() ? BuildTree(source.Enumerable2NonNullList(), idSelector.Compile(), pidSelector.Compile(), topValue).ToList() : throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
|
|
|
|
|
|
private static IEnumerable<T> BuildTree<T, TKey>(IEnumerable<T> source, Func<T, TKey> idSelector, Func<T, TKey> pidSelector, TKey topValue = default) where T : ITreeChildren<T> where TKey : IComparable
|
|
|
{
|
|
|
@@ -295,11 +271,9 @@ public static class TreeExtensions
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- internal static IEnumerable<T> BuildTree<T, TKey>(IEnumerable<T> source, TKey? topValue = null) where T : ITreeEntity<T, TKey> where TKey : struct, IComparable
|
|
|
- => BuildTree(source, t => t.Id, t => t.ParentId, topValue);
|
|
|
+ internal static IEnumerable<T> BuildTree<T, TKey>(IEnumerable<T> source, TKey? topValue = null) where T : ITreeEntity<T, TKey> where TKey : struct, IComparable => BuildTree(source, t => t.Id, t => t.ParentId, topValue);
|
|
|
|
|
|
- internal static IEnumerable<T> BuildTree<T>(IEnumerable<T> source, string topValue = null) where T : ITreeEntity<T>
|
|
|
- => BuildTree(source, t => t.Id, t => t.ParentId, topValue);
|
|
|
+ internal static IEnumerable<T> BuildTree<T>(IEnumerable<T> source, string topValue = null) where T : ITreeEntity<T> => BuildTree(source, t => t.Id, t => t.ParentId, topValue);
|
|
|
|
|
|
internal static IEnumerable<T> BuildTree<T>(IEnumerable<T> source, T parent) where T : ITreeEntity<T>
|
|
|
{
|
|
|
@@ -405,14 +379,7 @@ public static class TreeExtensions
|
|
|
/// <param name="pidSelector"></param>
|
|
|
/// <param name="topValue">根对象parentId的值</param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<Tree<T>> ToTreeGeneral<T, TKey>(this IEnumerable<T> source, Expression<Func<T, TKey>> idSelector, Expression<Func<T, TKey>> pidSelector, TKey topValue = default) where TKey : IComparable
|
|
|
- => idSelector.Body.ToString() != pidSelector.Body.ToString()
|
|
|
- ? BuildTreeGeneral(
|
|
|
- source.Where(t => t != null).ToList(),
|
|
|
- idSelector.Compile(),
|
|
|
- pidSelector.Compile(),
|
|
|
- topValue).ToList()
|
|
|
- : throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
|
|
|
+ public static List<Tree<T>> ToTreeGeneral<T, TKey>(this IEnumerable<T> source, Expression<Func<T, TKey>> idSelector, Expression<Func<T, TKey>> pidSelector, TKey topValue = default) where TKey : IComparable => idSelector.Body.ToString() != pidSelector.Body.ToString() ? BuildTreeGeneral(source.Where(t => t != null).ToList(), idSelector.Compile(), pidSelector.Compile(), topValue).ToList() : throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
|
|
|
|
|
|
private static IEnumerable<Tree<T>> BuildTreeGeneral<T, TKey>(List<T> list, Func<T, TKey> idSelector, Func<T, TKey> pidSelector, TKey parent) where TKey : IComparable
|
|
|
{
|
|
|
@@ -461,68 +428,57 @@ public static class TreeExtensions
|
|
|
/// <summary>
|
|
|
/// 所有子级
|
|
|
/// </summary>
|
|
|
- public static ICollection<T> AllChildren<T>(this T tree) where T : ITreeChildren<T>
|
|
|
- => GetChildren(tree, c => c.Children);
|
|
|
+ public static ICollection<T> AllChildren<T>(this T tree) where T : ITreeChildren<T> => GetChildren(tree, c => c.Children);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 所有子级
|
|
|
/// </summary>
|
|
|
- public static ICollection<T> AllChildren<T>(this T tree, Func<T, IEnumerable<T>> selector) where T : ITreeChildren<T>
|
|
|
- => GetChildren(tree, selector);
|
|
|
+ public static ICollection<T> AllChildren<T>(this T tree, Func<T, IEnumerable<T>> selector) where T : ITreeChildren<T> => GetChildren(tree, selector);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 所有子级
|
|
|
/// </summary>
|
|
|
- public static ICollection<Tree<T>> AllChildren<T>(this Tree<T> tree)
|
|
|
- => GetChildren(tree, c => c.Children);
|
|
|
+ public static ICollection<Tree<T>> AllChildren<T>(this Tree<T> tree) => GetChildren(tree, c => c.Children);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 所有子级
|
|
|
/// </summary>
|
|
|
- public static ICollection<Tree<T>> AllChildren<T>(this Tree<T> tree, Func<Tree<T>, IEnumerable<Tree<T>>> selector)
|
|
|
- => GetChildren(tree, selector);
|
|
|
+ public static ICollection<Tree<T>> AllChildren<T>(this Tree<T> tree, Func<Tree<T>, IEnumerable<Tree<T>>> selector) => GetChildren(tree, selector);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 所有父级
|
|
|
/// </summary>
|
|
|
- public static List<T> AllParent<T>(this T tree) where T : class, ITreeParent<T>
|
|
|
- => GetParents(tree, c => c.Parent);
|
|
|
+ public static List<T> AllParent<T>(this T tree) where T : class, ITreeParent<T> => GetParents(tree, c => c.Parent);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 所有父级
|
|
|
/// </summary>
|
|
|
- public static List<T> AllParent<T>(this T tree, Func<T, T> selector) where T : class, ITreeParent<T>
|
|
|
- => GetParents(tree, selector);
|
|
|
+ public static List<T> AllParent<T>(this T tree, Func<T, T> selector) where T : class, ITreeParent<T> => GetParents(tree, selector);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 所有父级
|
|
|
/// </summary>
|
|
|
- public static List<Tree<T>> AllParent<T>(this Tree<T> tree, Func<Tree<T>, Tree<T>> selector)
|
|
|
- => GetParents(tree, selector);
|
|
|
+ public static List<Tree<T>> AllParent<T>(this Tree<T> tree, Func<Tree<T>, Tree<T>> selector) => GetParents(tree, selector);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 是否是根节点
|
|
|
/// </summary>
|
|
|
- public static bool IsRoot<T>(this ITreeParent<T> tree) where T : ITreeParent<T>
|
|
|
- => tree.Parent == null;
|
|
|
+ public static bool IsRoot<T>(this ITreeParent<T> tree) where T : ITreeParent<T> => tree.Parent == null;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 是否是叶子节点
|
|
|
/// </summary>
|
|
|
- public static bool IsLeaf<T>(this ITreeChildren<T> tree) where T : ITreeChildren<T>
|
|
|
- => tree.Children?.Count == 0;
|
|
|
+ public static bool IsLeaf<T>(this ITreeChildren<T> tree) where T : ITreeChildren<T> => tree.Children?.Count == 0;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 是否是根节点
|
|
|
/// </summary>
|
|
|
- public static bool IsRoot<T>(this Tree<T> tree)
|
|
|
- => tree.Parent == null;
|
|
|
+ public static bool IsRoot<T>(this Tree<T> tree) => tree.Parent == null;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 是否是叶子节点
|
|
|
/// </summary>
|
|
|
- public static bool IsLeaf<T>(this Tree<T> tree)
|
|
|
- => tree.Children?.Count == 0;
|
|
|
+ public static bool IsLeaf<T>(this Tree<T> tree) => tree.Children?.Count == 0;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 深度层级
|
|
|
@@ -567,14 +523,12 @@ public static class TreeExtensions
|
|
|
/// <summary>
|
|
|
/// 节点路径(UNIX路径格式,以“/”分隔)
|
|
|
/// </summary>
|
|
|
- public static string Path<T>(this T tree) where T : class, ITree<T>
|
|
|
- => GetFullPath(tree, t => t.Name);
|
|
|
+ public static string Path<T>(this T tree) where T : class, ITree<T> => GetFullPath(tree, t => t.Name);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 节点路径(UNIX路径格式,以“/”分隔)
|
|
|
/// </summary>
|
|
|
- public static string Path<T>(this T tree, Func<T, string> selector) where T : class, ITreeParent<T>
|
|
|
- => GetFullPath(tree, selector);
|
|
|
+ public static string Path<T>(this T tree, Func<T, string> selector) where T : class, ITreeParent<T> => GetFullPath(tree, selector);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 节点路径
|
|
|
@@ -591,14 +545,12 @@ public static class TreeExtensions
|
|
|
/// <param name="selector">选择字段</param>
|
|
|
/// <param name="separator">分隔符</param>
|
|
|
/// <returns></returns>
|
|
|
- public static string Path<T>(this T tree, Func<T, string> selector, string separator) where T : class, ITreeParent<T>
|
|
|
- => GetFullPath(tree, selector, separator);
|
|
|
+ public static string Path<T>(this T tree, Func<T, string> selector, string separator) where T : class, ITreeParent<T> => GetFullPath(tree, selector, separator);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 根节点
|
|
|
/// </summary>
|
|
|
- public static T Root<T>(this T tree) where T : class, ITreeParent<T>
|
|
|
- => GetRoot(tree, t => t.Parent);
|
|
|
+ public static T Root<T>(this T tree) where T : class, ITreeParent<T> => GetRoot(tree, t => t.Parent);
|
|
|
|
|
|
private static string GetFullPath<T>(T c, Func<T, string> selector, string separator = "/") where T : class, ITreeParent<T>
|
|
|
{
|
|
|
@@ -642,10 +594,12 @@ public static class TreeExtensions
|
|
|
throw new InvalidOperationException("节点存在循环引用");
|
|
|
|
|
|
var parent = selector(currentNode);
|
|
|
- if (parent != null)
|
|
|
- currentNode = parent;
|
|
|
- else
|
|
|
- return currentNode;// 找到了根节点
|
|
|
+ if (parent == null)
|
|
|
+ {
|
|
|
+ return currentNode; // 找到了根节点
|
|
|
+ }
|
|
|
+
|
|
|
+ currentNode = parent;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -668,13 +622,9 @@ public static class TreeExtensions
|
|
|
var current = queue.Dequeue();
|
|
|
list.Add(current); // 将当前节点添加到结果列表
|
|
|
var children = selector(current) ?? new List<T>();
|
|
|
- foreach (var child in children)
|
|
|
+ foreach (var child in children.Where(child => selector(child).Any()))
|
|
|
{
|
|
|
- // 只有当子节点还有自己的子节点时,才将其加入队列
|
|
|
- if (selector(child).Any())
|
|
|
- {
|
|
|
- queue.Enqueue(child);
|
|
|
- }
|
|
|
+ queue.Enqueue(child);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -726,8 +676,7 @@ public static class TreeExtensionLong
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
/// <param name="source"></param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, long>
|
|
|
- => source.ToTree<T, long>();
|
|
|
+ public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, long> => source.ToTree<T, long>();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -741,8 +690,7 @@ public static class TreeExtensionGuid
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
/// <param name="source"></param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, Guid>
|
|
|
- => source.ToTree<T, Guid>();
|
|
|
+ public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, Guid> => source.ToTree<T, Guid>();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -757,8 +705,7 @@ public static class TreeExtensionString
|
|
|
/// <param name="source"></param>
|
|
|
/// <param name="topValue"></param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T>(this IEnumerable<T> source, string topValue) where T : class, ITreeEntity<T>
|
|
|
- => TreeExtensions.BuildTree(source.Enumerable2NonNullList(), topValue).ToList();
|
|
|
+ public static List<T> ToTree<T>(this IEnumerable<T> source, string topValue) where T : class, ITreeEntity<T> => TreeExtensions.BuildTree(source.Enumerable2NonNullList(), topValue).ToList();
|
|
|
|
|
|
/// <summary>
|
|
|
/// 平行集合转换成树形结构
|
|
|
@@ -766,12 +713,10 @@ public static class TreeExtensionString
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
/// <param name="source"></param>
|
|
|
/// <returns></returns>
|
|
|
- public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T>
|
|
|
- => source.Enumerable2NonNullList()
|
|
|
- .Where(t => string.IsNullOrEmpty(t.ParentId))
|
|
|
- .SelectMany(parent => TreeExtensions.BuildTree(source, parent)).ToList();
|
|
|
+ public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T> => source.Enumerable2NonNullList().Where(t => string.IsNullOrEmpty(t.ParentId)).SelectMany(parent => TreeExtensions.BuildTree(source, parent)).ToList();
|
|
|
}
|
|
|
-file static class TreeExtensionCommon
|
|
|
+
|
|
|
+internal static class TreeExtensionCommon
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 将IEnumerable转换成不含null的List,若T为IQueryable,则将数据读取到内存
|
|
|
@@ -781,12 +726,7 @@ file static class TreeExtensionCommon
|
|
|
/// <returns></returns>
|
|
|
public static List<T> Enumerable2NonNullList<T>(this IEnumerable<T> source)
|
|
|
{
|
|
|
- source = source is IQueryable<T> queryable
|
|
|
- ? queryable.AsEnumerable()
|
|
|
- : source;
|
|
|
- return (typeof(T).IsValueType
|
|
|
- ? source
|
|
|
- : source.Where(t => t != null))
|
|
|
- .ToList();
|
|
|
+ source = source is IQueryable<T> queryable ? queryable.AsEnumerable() : source;
|
|
|
+ return (typeof(T).IsValueType ? source : source.Where(t => t != null)).ToList();
|
|
|
}
|
|
|
}
|