using System; using System.Collections.Generic; using System.Linq; namespace Masuit.Tools.Core.Models { /// /// 树形数据扩展 /// public static class TreeExtensions { /// /// 过滤 /// /// /// /// /// public static IEnumerable Filter(this IEnumerable items, Func func) where T : ITree { 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 : ITree { return (new[] { item }).Filter(func); } /// /// 平铺开 /// /// /// /// public static IEnumerable Flatten(this IEnumerable items) where T : ITree { var result = new List(); foreach (var item in items) { result.Add(item); result.AddRange(item.Children.Flatten()); } return result; } /// /// 所有子级 /// public static ICollection AllChildren(this ITree tree) where T : ITree => GetChildren(tree); /// /// 所有父级 /// public static ICollection AllParent(this ITree tree) where T : ITree => GetParents(tree); /// /// 是否是根节点 /// public static bool IsRoot(this ITree tree) where T : ITree => tree.Parent == null; /// /// 是否是叶子节点 /// public static bool IsLeaf(this ITree tree) where T : ITree => tree.Children.Count == 0; /// /// 深度 /// public static int Level(this ITree tree) where T : ITree => IsRoot(tree) ? 0 : 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(ITree t) where T : ITree { return t.Children.Union(t.Children.Where(c => c.Children.Any()).SelectMany(tree => GetChildren(tree))).ToList(); } /// /// 递归取出所有上级 /// /// /// private static List GetParents(ITree t) where T : ITree { var list = new List() { t.Parent }; return t.Parent != null ? list.Union(GetParents(t.Parent)).ToList() : list; } } }