C# 如何使用linq对嵌套数据进行排序
我有这样一个分类表:C# 如何使用linq对嵌套数据进行排序,c#,linq,C#,Linq,我有这样一个分类表: id parentid Title 1 0 Parent1 2 1 Child1 3 0 Parent2 4 3 Child2 5 1 anotherChild1 6 3 anotherChild2 如何按以下顺序对其进行排序: Parent1 child1 anotherchild1 Parent2 child2 another
id parentid Title
1 0 Parent1
2 1 Child1
3 0 Parent2
4 3 Child2
5 1 anotherChild1
6 3 anotherChild2
如何按以下顺序对其进行排序:
Parent1
child1
anotherchild1
Parent2
child2
anotherchild2
并将顺序保存到另一个名为排序索引的字段中?这适用于任何层次结构
public void CustomSort()
{
List<MyNode> nodes = new List<MyNode>();
nodes.Add(new MyNode() { Id = 5, ParentId = 1, Title = "Anotherchild1" });
nodes.Add(new MyNode() { Id = 6, ParentId = 3, Title = "Anotherchild2" });
nodes.Add(new MyNode() { Id = 7, ParentId = 6, Title = "Anotherchild3" });
nodes.Add(new MyNode() { Id = 1, ParentId = 0, Title = "Parent1" });
nodes.Add(new MyNode() { Id = 2, ParentId = 1, Title = "Child1" });
nodes.Add(new MyNode() { Id = 3, ParentId = 0, Title = "Parent2" });
nodes.Add(new MyNode() { Id = 4, ParentId = 3, Title = "Child2" });
Func<MyNode, List<int>> hierarchy = null;
hierarchy = n =>
{
var n2 = nodes.FirstOrDefault(x => x.Id == n.ParentId);
if (n2 != null) return hierarchy(n2).Concat(new List<int>() { n.Id }).ToList();
return new List<int>() { n.ParentId,n.Id };
};
var debug = nodes.Select(x=>hierarchy(x)).ToList();
var sortedList = nodes.OrderBy(n => String.Join(",", hierarchy(n).Select(x=>x.ToString("X8"))))
.ToList();
}
class MyNode
{
public int Id;
public int ParentId;
public string Title;
}
如果您的继承权只有两个级别,那么您可以将父母与子女合并,展平结果列表,然后包含每个人的索引
var parents = people.Where(p => p.ParentId < 1).ToList();
var children = people.Where(p => p.ParentId >= 1).ToList();
var ordered = (from parent in parents
join child in children on parent.Id equals child.ParentId into childGroup
from person in (new [] { parent }).Concat(childGroup)
select person)
.Select((person, sortedIndex) => new { person, sortedIndex });
嗨,L.B,非常感谢你的回答,我很忙,你能解释一下你是如何得到层次结构的吗?为什么要转换成stringx8?@Kiddo 1 hierarcy是一个递归函数。它使用节点返回hierarchyn2的parentid调用自己,并在展开时收集节点的id。解释递归函数比编写更难:。2我从列表中形成一个字符串。例如,0 1 2转换为0000000 10002。原因是您无法将列表与a==b进行比较,因为它们是引用类型。另一种选择是编写定制的iComparer,这可能更好,但这会增加答案的大小,让每个人都感到害怕。
var parents = people.Where(p => p.ParentId < 1).ToList();
var children = people.Where(p => p.ParentId >= 1).ToList();
var ordered = (from parent in parents
join child in children on parent.Id equals child.ParentId into childGroup
from person in (new [] { parent }).Concat(childGroup)
select person)
.Select((person, sortedIndex) => new { person, sortedIndex });