我最难将列表(Of Folder)转换为层次结构。
Public Class Folder
Public Property FolderID() As Integer
Public Property Name() As String
Public Property ParentFolderID() As Integer
Public Property Children() as IEnumerable(Of Folder)
End Class
我需要返回包含子项的List(Of Folder)。
我从数据库中的数据构建一个List(Of Folder)。
{1,“文件夹1”,没什么} {2,“文件夹2”,1} {3,“文件夹3”,2} {4,“文件夹4”,3} {5,“文件夹5”,没什么}
我无法弄清楚如何以递归方式将子文件夹移动到其父级的Children属性中。
我想用LINQ做这个。
非常感谢任何帮助。
更新
感谢您的回答,但不是那里。根据你的答案,我想出了几乎可行的。
Dim list = (From folder in folderList Select New Folder() With {
.FolderID = folder.FolderID,
.Name = folder.Name,
.ParentFolderID = folder.ParentFolderID,
.Children = (From child in folderList
Where child.ParentFolderID = item.FolderID).ToList()}).ToList()
{1, "Root", Nothing}
{2, "Child", 1}
{3, "Grand Child", 2}
我得到了所有三个文件夹的列表:
Root
--Child
Child
--Grand Child
Grand Child
应该是这样的:
Root
--Child
----Grand Child
答案 0 :(得分:12)
如果您使用ToLookup
扩展方法,则很容易。
C#:
var lookup = folderList.ToLookup(f => f.ParentFolderID);
foreach (var folder in folderList)
{
folder.Children = lookup[folder.FolderID].ToList();
}
var rootFolders = lookup[null].ToList();
VB:
Dim lookup = folderList.ToLookup(Function (f) f.ParentFolderID)
For Each folder In folderList
folder.Children = lookup(folder.FolderID).ToList()
Next
Dim rootFolders = lookup(Nothing).ToList()
答案 1 :(得分:0)
C#版
var newList = list.Select(o=>
new Fodler
{
FodlerID = o.FodlerID,
Children = list.Where(q => q.ParentId == o.FodlerID),
Parent = list.FirstOrDefault(q => q.FodlerID == o.ParentID ),
//Other properties goes here
});
虽然如果你在例如正确的映射中进行EF,它应该自动完成。
答案 2 :(得分:0)
试试这个扩展方法:
public static IEnumerable<T> AsHierarchy<T>(this IEnumerable<T> collection,
Func<T, T> parentSelector, Expression<Func<T, IEnumerable<T>>> childrenSelector, T root = default(T))
{
var items = collection.Where(x => parentSelector(x).Equals(root));
foreach (var item in items)
{
var childrenProperty = (childrenSelector.Body as MemberExpression).Member as PropertyInfo;
childrenProperty.SetValue(item, collection.AsHierarchy(parentSelector, childrenSelector, item), null);
}
return items;
}
然后,您可以像这样使用它:
list.AsHierarchy(x => x.Parent, x => x.Children);