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 IEnumerable Flatten(this IEnumerable items, Func> selector) { var result = new List(); foreach (var item in items) { result.Add(item); result.AddRange(selector(item).Flatten(selector)); } return result; } /// /// 所有子级 /// public static ICollection AllChildren(this T tree) where T : ITreeChildren => GetChildren(tree, c => c.Children); /// /// 所有子级 /// public static ICollection AllChildren(this T tree, Func> selector) => GetChildren(tree, selector); /// /// 所有父级 /// public static ICollection AllParent(this T tree) where T : ITreeParent => GetParents(tree, c => c.Parent); /// /// 所有父级 /// public static ICollection AllParent(this T tree, Func selector) => GetParents(tree, selector); /// /// 是否是根节点 /// 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 T tree) where T : ITree => GetFullPath(tree, t => t.Name); /// /// 节点路径(UNIX路径格式,以“/”分隔) /// public static string Path(this T tree, Func selector) where T : ITreeParent => GetFullPath(tree, selector); private static string GetFullPath(T c, Func selector) where T : ITreeParent => c.Parent != null ? GetFullPath(c.Parent, selector) + "/" + selector(c) : selector(c); /// /// 递归取出所有下级 /// /// /// private static List GetChildren(T t, Func> selector) { return selector(t).Union(selector(t).Where(c => selector(c).Any()).SelectMany(c => GetChildren(c, selector))).ToList(); } /// /// 递归取出所有上级 /// /// /// private static List GetParents(T t, Func selector) { var list = new List() { selector(t) }; if (selector(t) != null) { return list.Union(GetParents(selector(t), selector)).Where(x => x != null).ToList(); } list.RemoveAll(x => x == null); return list; } } }