2011-01-14 21 views
8

リスト(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 

子どもが入っているリスト(Of Folder)を返す必要があります。

データベースのデータからList(Of Folder)を構築します。

{1、 "フォルダ1"、何も} {2、 "フォルダ2"、1} {3、 "フォルダ3"、2} {4、 "フォルダ4"、3} {5 、 "Folder 5"、Nothing}

子フォルダを再帰的に親の子プロパティに移動する方法を知ることはできません。

私はLINQでこれを行いたいと思います。

ご協力いただきまして誠にありがとうございます。

更新はなく、かなりそこに、あなたの答えをいただき、ありがとうございます。あなたの答えに基づいて、私はこれを考え出しました。

Root 
--Child 
Child 
--Grand Child 
Grand Child 

は、次のようになります:

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} 

は、私はすべての3つのフォルダの一覧を取得

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:、その後

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; 
    } 

あなたはこのようにそれを使用することができます:

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拡張機能をうまく使います。 –

0

は、この拡張メソッドを試してみてください

list.AsHierarchy(x => x.Parent, x => x.Children); 
+1

こんにちは。このスニペットは私にとって非常に戸惑うようですが、それを呼び出す方法は? 私はx => x.Parentを理解していませんか?誰かが正しい方向に私を指す例を与えることができますか? – m33

+0

上記の拡張メソッドを静的クラスに作成して使用する必要があります。最初のパラメータは親ノードを見つける方法を指定し、2番目のパラメータは子コレクションを取得する方法を指定します。 –