using System; using System.Collections.Generic; using System.Linq; namespace Masuit.Tools.Models { /// /// 树形数据扩展 /// public static class TreeExtensions { /// /// 过滤 /// /// /// /// /// public static IEnumerable Filter(this IEnumerable items, Func func) where T : ITreeChildren { var results = new List(); foreach (var item in items.Where(i => i != null)) { item.Children = item.Children.Filter(func).ToList(); if (item.Children.Any() || func(item)) { results.Add(item); } } return results; } /// /// 过滤 /// /// /// /// /// public static IEnumerable Filter(this T item, Func func) where T : ITreeChildren { return new[] { item }.Filter(func); } /// /// 平铺开 /// /// /// /// public static IEnumerable Flatten(this IEnumerable items) where T : ITreeChildren { var result = new List(); foreach (var item in items) { result.Add(item); result.AddRange(item.Children.Flatten()); } return result; } /// /// 所有子级 /// public static ICollection AllChildren(this ITreeChildren tree) where T : ITreeChildren => GetChildren(tree); /// /// 所有父级 /// public static ICollection AllParent(this ITreeParent tree) where T : ITreeParent => GetParents(tree); /// /// 是否是根节点 /// public static bool IsRoot(this ITreeParent tree) where T : ITreeParent => tree.Parent == null; /// /// 是否是叶子节点 /// public static bool IsLeaf(this ITreeChildren tree) where T : ITreeChildren => tree.Children?.Count == 0; /// /// 深度层级 /// public static int Level(this ITreeParent tree) where T : ITreeParent => IsRoot(tree) ? 1 : Level(tree.Parent) + 1; /// /// 节点路径(UNIX路径格式,以“/”分隔) /// public static string Path(this ITree tree) where T : ITree => GetFullPath(tree); private static string GetFullPath(ITree c) where T : ITree => c.Parent != null ? GetFullPath(c.Parent) + "/" + c.Name : c.Name; /// /// 递归取出所有下级 /// /// /// private static List GetChildren(ITreeChildren t) where T : ITreeChildren { return t.Children.Union(t.Children.Where(c => c.Children.Any()).SelectMany(tree => GetChildren(tree))).ToList(); } /// /// 递归取出所有上级 /// /// /// private static List GetParents(ITreeParent t) where T : ITreeParent { var list = new List() { t.Parent }; return t.Parent != null ? list.Union(GetParents(t.Parent)).ToList() : list; } } }