C# 按父项和子项以及子项的父项排序的订单列表
我正在试着订购一份应该是这样的清单C# 按父项和子项以及子项的父项排序的订单列表,c#,linq,C#,Linq,我正在试着订购一份应该是这样的清单 母公司 Child1(同时为孩子和家长) 子女2(子女1的子女) 孩子3 在使用包含有关ID、ParentID等信息的类时 我尝试使用LINQ来实现这一点,并尝试了不同的解决方案,但没有人能完全实现,我知道递归函数可以实现(但我真的不喜欢),有人能帮我实现使用LINQ吗 我尝试了这个代码,但是Child2没有出现 List<Person> orderedList = new List<Person>();
- Child1(同时为孩子和家长)
- 子女2(子女1的子女)
- 孩子3
List<Person> orderedList = new List<Person>();
persons.ForEach(x => {
if (x.ParentID == 0) {
orderedList.Add(x);
orderedList.AddRange(persons.Where(child => child.ParentID == x.Id));
}
});
List orderedList=new List();
persons.ForEach(x=>{
如果(x.ParentID==0){
orderedList.Add(x);
orderedList.AddRange(persons.Where(child=>child.ParentID==x.Id));
}
});
对于那些投“反对票”的人,请记住,在一开始编程时,没有人是上帝,如果我来到这里,这意味着我要在x小时内努力解决这个问题。而且,如果你认为我的英语不好,我已经知道了,我不是生来就能说一口流利的英语的,但是那些想帮忙的人会帮忙的
全部代码
public class Person{
public int Id { get; set; }
public string MenuName { get; set; }
public int? ParentID { get; set; }
public string isHidden { get; set; }
public string LinkURL { get; set; }
}
public static List<Person> AddPersons(){
var persons = new List<Person>();
using (var reader = new StreamReader(@"C:\Users\AceDuk\Desktop\Navigation.csv")){
var line = reader.ReadLine(); //Da se izbegne headerot
while ((line = reader.ReadLine()) != null){
var values = line.Split(';');
if (values[2] == "NULL") {
values[2] = "0";
}
persons.Add(new Person(){
Id = Int32.Parse(values[0]),
MenuName = values[1],
ParentID = Int32.Parse(values[2]),
isHidden = values[3],
LinkURL = values[4]
});
}
}
persons.RemoveAll(x => x.isHidden == "True"); //Izbrisi gi site sto se hidden ne gi pokazuvaj..
//persons = persons.OrderBy(x => x.MenuName).ToList(); //Ordered
persons = persons.OrderBy(x => x.LinkURL).ToList(); //Ordered
return persons;
}
static void Main(string[] args){
List<Person> persons = AddPersons();
List<Person> orderedList = new List<Person>();
persons.ForEach(x => {
if (x.ParentID == 0) {
orderedList.Add(x);
orderedList.AddRange(persons.Where(child => child.ParentID == x.Id));
}
});
foreach (var item in orderedList) {
Console.WriteLine(item.MenuName);
}
}
公共类人物{
公共int Id{get;set;}
公共字符串菜单名{get;set;}
public int?ParentID{get;set;}
公共字符串isHidden{get;set;}
公共字符串链接URL{get;set;}
}
公共静态列表AddPersons(){
var persons=新列表();
使用(var reader=new StreamReader(@“C:\Users\AceDuk\Desktop\Navigation.csv”)){
var line=reader.ReadLine();//Da se izbegne headerot
而((line=reader.ReadLine())!=null){
变量值=行分割(“;”);
如果(值[2]=“空”){
值[2]=“0”;
}
人员。添加(新人员(){
Id=Int32.Parse(值[0]),
MenuName=值[1],
ParentID=Int32.Parse(值[2]),
isHidden=值[3],
LinkURL=值[4]
});
}
}
persons.RemoveAll(x=>x.ishiden==“True”);//Izbrisi-gi-site将隐藏的ne-gi-pokazuvaj。。
//persons=persons.OrderBy(x=>x.MenuName.ToList();//有序
persons=persons.OrderBy(x=>x.LinkURL.ToList();//有序
返回人员;
}
静态void Main(字符串[]参数){
列出人员=添加人员();
List orderedList=新列表();
persons.ForEach(x=>{
如果(x.ParentID==0){
orderedList.Add(x);
orderedList.AddRange(persons.Where(child=>child.ParentID==x.Id));
}
});
foreach(orderedList中的变量项){
Console.WriteLine(item.MenuName);
}
}
通过扩展链表创建双端队列(deque)数据结构:
public class Deque<T> : LinkedList<T> {
public void Enqueue(T item) => AddLast(item);
public T Dequeue() {
var item = First.Value;
RemoveFirst();
return item;
}
public void EnqueueRange(IEnumerable<T> items) {
foreach (var item in items)
Enqueue(item);
}
public void Push(T item) => AddFirst(item);
public T Pop() => Dequeue();
public void PushRange(IEnumerable<T> items) {
foreach (var item in items)
Push(item);
}
public T Peek() => Last.Value;
}
最后,使用deque创建工作列表并添加所有根节点:
var workDeque = new Deque<Person>();
workDeque.EnqueueRange(persons.Where(p => p.ParentID == 0));
编程不涉及“缩进”。在编程环境中,“缩进”是什么意思?拼写错误,编辑错误:)LINQ在处理分层数据时非常糟糕。有一些不错的选项涉及循环和数据结构(不是LINQ),但您没有解释为什么不喜欢递归选项。递归非常适合您所描述的内容,而相比之下,其他任何东西都可能会很笨拙。我已经使用递归数百次来解决类似的问题。Linq不适合这种类型的代码。我不知道可能是因为我不知道如何递归地执行它。。。我想也许可以从列表中创建第一棵树,然后遍历元素并打印。。
var workDeque = new Deque<Person>();
workDeque.EnqueueRange(persons.Where(p => p.ParentID == 0));
var orderedPersons = new List<Person>();
while (workDeque.Count > 0) {
var nextPerson = workDeque.Dequeue();
orderedPersons.Add(nextPerson);
workDeque.PushRange(childrenDictionary[nextPerson.Id]);
}