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