我有一个小的层次结构。例如:
实体:
public class MyClass
{
public int ID { get; set; }
public string Name { get; set; }
public int ParentID { get; set; }
}
我的层次结构数据如下所示:
Id = 1 Name = Item1 ParentId = NULL
Id = 2 Name = Item2 ParentId = 1
Id = 3 Name = Item3 ParentId = 2
Id = 4 Name = Item4 ParentId = 2
Id = 5 Name = Item5 ParentId = 3
问题是我需要对子节点必须在其直接父节点之后进行排序。下面的示例必须看起来像
Id = 1 Name = Item1 ParentId = NULL
Id = 2 Name = Item2 ParentId = 1
Id = 3 Name = Item3 ParentId = 2
// the elements with parentID = 3
Id = 5 Name = Item5 ParentId = 3
//continue
Id = 4 Name = Item4 ParentId = 2
任何广告?
答案 0 :(得分:0)
假设您有_list
个MyClass
个对象,请先在Name
字段,然后在ParentId
字段中对其进行排序,如下所示,使用LINQ:
_list.OrderBy(L=>L.Name).ThenBy(L=>L.ParentId);
希望这可能会有所帮助。
答案 1 :(得分:0)
试试这个 我假设你想要按照parentid和每个父母的顺序排序,你想按ID排序。
myClassList.OrderBy(parent=>parent.ParentId).ThenBy(parent=>parent.Id);
答案 2 :(得分:0)
试试这个递归代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyClass.data = new List<MyClass>() {
new MyClass() { ID = 1, Name = "Item1", ParentID = null},
new MyClass() { ID = 2, Name = "Item2", ParentID = 1 },
new MyClass() { ID = 3, Name = "Item3", ParentID = 2 },
new MyClass() { ID = 4, Name = "Item4", ParentID = 2 },
new MyClass() { ID = 5, Name = "Item5", ParentID = 3 }
};
MyClass myClass = new MyClass();
myClass.GetData(null, 0);
Console.ReadLine();
}
}
public class MyClass
{
public static List<MyClass> data = null;
public int ID { get; set; }
public string Name { get; set; }
public int? ParentID { get; set; }
public void GetData(int? id, int level)
{
List<MyClass> children = data.Where(x => x.ParentID == id).ToList();
foreach (MyClass child in children)
{
Console.WriteLine(" {0} ID : {1}, Name : {2}, Parent ID : {3}", new string(' ',4 * level),child.ID, child.Name, child.ParentID);
GetData(child.ID, level + 1);
}
}
}
}
答案 3 :(得分:0)
在这里你有办法做到这一点。正如您所看到的,我覆盖了ToString
方法,并添加了一些案例。
public class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
public override string ToString()
{
return string.Format("{0}: {1} - {2}", Id, Name, ParentId);
}
}
class Program
{
static void Main(string[] args)
{
List<MyClass> list = new List<MyClass>();
list.Add(new MyClass { Id = 1, Name = "Item1", ParentId = null });
list.Add(new MyClass { Id = 2, Name = "Item2", ParentId = 1 });
list.Add(new MyClass { Id = 3, Name = "Item3", ParentId = 2 });
list.Add(new MyClass { Id = 4, Name = "Item4", ParentId = 2 });
list.Add(new MyClass { Id = 5, Name = "Item5", ParentId = 3 });
list.Add(new MyClass { Id = 6, Name = "Item6", ParentId = 1 });
list.Add(new MyClass { Id = 7, Name = "Item7", ParentId = null });
list.Add(new MyClass { Id = 8, Name = "Item8", ParentId = 2 });
list.Add(new MyClass { Id = 9, Name = "Item9", ParentId = 6 });
list.Add(new MyClass { Id = 10, Name = "Item10", ParentId = 7 });
foreach(var item in list.Where(x => !x.ParentId.HasValue).OrderBy(x => x.Id))
ProcessItem(item, list, 0);
Console.ReadKey();
}
private static void ProcessItem(MyClass item, List<MyClass> list, int level)
{
Console.WriteLine("{0}{1}", new string(' ', level * 2), item.ToString());
foreach (var subitem in list.Where(x => x.ParentId == item.Id).OrderBy(x => x.Id))
ProcessItem(subitem, list, level + 1);
}
}
这样的事情对你有用吗?
如果您需要实际的有序列表,请尝试以下方法:
foreach (var item in OrderList(list))
Console.WriteLine(item.ToString());
(...)
private static List<MyClass> OrderList(List<MyClass> list)
{
List<MyClass> orderedList = new List<MyClass>(list.Count());
foreach (var item in list.Where(x => !x.ParentId.HasValue).OrderBy(x => x.Id))
AddItem(item, list, orderedList);
return orderedList;
}
private static void AddItem(MyClass item, List<MyClass> list, List<MyClass> orderedList)
{
orderedList.Add(item);
foreach (var subitem in list.Where(x => x.ParentId == item.Id).OrderBy(x => x.Id))
AddItem(subitem, list, orderedList);
}
答案 4 :(得分:0)
以下应该做的伎俩(并显示一些更好的性能,因为我们在查找中保存层次结构,而不是动态搜索IEnumerable):
public List<MyClass> SortHierarchically(IEnumerable<MyClass> myClasses)
{
if(myClasses == null)
return new List<MyClass>();
var myClassesByParentId = myClasses.ToLookup(mc => mc.ParentId);
var result = new List<MyClass>(myClasses.Count());
int? currentParentId = null;
MyClass currentItem = myClassesByParentId[currentParentId].Single();
result.Add(currentItem);
currentParentId = currentItem.Id;
if(myClassesByParentId.Contains(currentParentId))
result.AddRange(myClassesByParentId[currentParentId].SelectMany(mc => GetAllSortedChildren(mc, myClassesByParentId)));
return result;
}
public List<MyClass> GetAllSortedChildren(MyClass parent, ILookup<int?, MyClass> myClassesByParentId)
{
var result = new List<MyClass>() { parent };
if(myClassesByParentId.Contains(parent.Id))
retsult.AddRange(myClassesByParentId[parent.Id].SelectMany(mc => GetAllSortedChildren(mc, myClassesByParentId)));
return result;
}
找到一种通过标准LINQ对其进行排序的方法,以及一些聪明的比较器等,将会很有趣。
答案 5 :(得分:0)
上述答案之一效果很好。这是一个通用版本。
public static class SortingMethods
{
public static IList<T> OrderByHierarchical<T>(
this IEnumerable<T> items,
Func<T, string> getId,
Func<T, string> getParentId)
{
if (items == null)
return new List<T>();
var itemsByParentId = items.ToLookup(item => getParentId(item));
var result = new List<T>(items.Count());
var currentParentId = "";
var currentItem = itemsByParentId[currentParentId].Single();
result.Add(currentItem);
currentParentId = getId(currentItem);
if (itemsByParentId.Contains(currentParentId))
result.AddRange(itemsByParentId[currentParentId].SelectMany(item => GetAllSortedChildren(item, itemsByParentId, getId)));
return result;
}
private static IList<T> GetAllSortedChildren<T>(T parent, ILookup<string, T> itemsByParentId, Func<T, string> getId)
{
var result = new List<T>() { parent };
if (itemsByParentId.Contains(getId(parent)))
{
result.AddRange(itemsByParentId[getId(parent)].SelectMany(item => GetAllSortedChildren(item, itemsByParentId, getId)));
}
return result;
}
}