2011-01-14 157 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