C# List 转 Tree 公共方法
2024-08-26 15:19:12
用C# 写了个List数据结构转树形数据结构的公共扩展方法
/// <summary>
/// 将列表转换为树形结构
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="list">数据</param>
/// <param name="rootwhere">根条件</param>
/// <param name="childswhere">节点条件</param>
/// <param name="addchilds">添加子节点</param>
/// <param name="entity"></param>
/// <returns></returns>
public static List<T> ToTree<T>(this List<T> list, Func<T, T, bool> rootwhere, Func<T, T, bool> childswhere, Action<T, IEnumerable<T>> addchilds, T entity = default(T))
{
var treelist = new List<T>();
//空树
if (list == null || list.Count == 0)
{
return treelist;
}
if (!list.Any<T>(e => rootwhere(entity, e)))
{
return treelist;
}
//树根
if (list.Any<T>(e => rootwhere(entity, e)))
{
treelist.AddRange(list.Where(e => rootwhere(entity, e)));
}
//树叶
foreach (var item in treelist)
{
if (list.Any(e => childswhere(item, e)))
{
var nodedata = list.Where(e => childswhere(item, e)).ToList();
foreach (var child in nodedata)
{
//添加子集
var data = list.ToTree(childswhere, childswhere, addchilds, child);
addchilds(child, data);
}
addchilds(item, nodedata);
}
}
return treelist;
}
方法说明:
第一个参数:根节点的条件
第二个参数:根节点和子节点的关系(注意,这地方如果条件不充分,会导致异常,无限递归)
第三个参数:当前数据添加子集
调用示例1、(id--->pid)
var treedata = list.ToTree<TTest>((r, c) =>
{
return c.Pid == 0;
},
(r, c) =>
{
return r.Id == c.Pid;
},
(r, datalist) =>
{
r.Childs = r.Childs ?? new List<TTest>();
r.Childs.AddRange(datalist);
});
调用示例2、(LevelCode)
treedata2 = liststr2.ToTree<TTest>((r, c) => c.LevelCode.Length == 6, (r, c) =>
{
if (r == null || c == null)
{
return false;
}
if ((r.LevelCode.Length + 6 == c.LevelCode.Length) &&
r.LevelCode == c.LevelCode.Substring(0, r.LevelCode.Length))
{
return true;
}
else
{
return false;
}
},
(r, datalist) => {
r.Childs = r.Childs ?? new List<TTest>();
r.Childs.AddRange(datalist);
});
最新文章
- 【转】RadControls for Silverlight(学习1-GridView)
- wordpress the_date 方法 偶尔为空的问题
- exit和_exit的区别
- Unix-Linux编程实践 学习点滴
- delphi 立即显示提示
- BCB 语言类
- Oracle 序列(sequence)
- 4. Linux 系统目录
- Struts2 整合jQuery实现Ajax功能(2)
- Tarjan算法:求解图的割点与桥(割边)
- 程序猿媛 九:Adroid zxing 二维码3.1集成(源码无删减)
- 一个tomcat设置多个端口,多个端口对应多个应用
- 使用shiro的密码服务模块
- 3、简单了解Angular应用的启动过程
- android插件化简述
- SparkSQL大数据实战:揭开Join的神秘面纱
- line-height:150% 和 line-height:1.5的区别
- spring 学习总结(一)
- Config Static IP Address manually in Ubuntu
- js判断触摸方向
热门文章
- Tosca case status PLANNED,IN-WORK,COMPLETED 对应的图标
- ByteBuffer使用实例
- [译]如何将dataframe的两列结合起来?
- 报错:java.lang.ClassNotFoundException: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException
- 【物联网】UI设计
- Dotmemory 内存分析工具的操作手册
- Intellij热部署插件JRebel的详细配置及图解
- Ubuntu 18.04 使用标准Ubuntu 仓库进行自动化安装NVIDIA驱动
- svn查看登录过的账号密码
- ztree通过id获取节点对象