2011-01-14 113 views
8

我正在將列表(文件夾)轉換爲層次結構最困難。平面列表到層次結構

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)。

{1, 「文件夾1」,沒有什麼} {2, 「文件夾2」,1} {3中, 「文件夾3」,2} {4中, 「文件夾4」,3} {5 ,「文件夾5」,什麼都沒有}

我想不出如何遞歸移動子文件夾到他們的父母的兒童財產。

我想用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

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,它應該自動完成。

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() 
+0

ToLookup擴展的很好用法。 – 2012-02-19 23:23:42

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); 
+1

嗨。這段代碼對我來說似乎很有意思,但是如何調用它呢? 我不明白x => x.Parent?任何人都可以舉個例子來指出我朝着正確的方向嗎? – m33 2016-01-26 11:07:27