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;
}
}
}