2009-06-02 23 views
0

これを行うにはLINQの方法はありますか?どんな助けでも大歓迎です。linqを使用して親子プロパティをマージする

var all = parentCollection.Select(p=>p.Name) 
     .Concat(parentCollection 
        .SelectMany(p=>p.Children).Select(c=>c.Name)); 

注意はこれが唯一の親/子関係の1つの深さで動作します:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Parent parent1 = new Parent(); 
     parent1.Name = "P1"; 


     Parent parent2 = new Parent(); 
     parent2.Name = "P2"; 


     Child child1 = new Child(); 
     child1.Name = "C1"; 

     Child child2 = new Child(); 
     child2.Name = "C2"; 

     Child child3 = new Child(); 
     child3.Name = "C3"; 

     Child child4 = new Child(); 
     child4.Name = "C4"; 


     parent1.Children.Add(child1); 
     parent1.Children.Add(child2); 


     parent2.Children.Add(child3); 
     parent2.Children.Add(child4); 

     List<Parent> parentCollection = new List<Parent>(); 
     parentCollection.Add(parent1); 
     parentCollection.Add(parent2); 



     List<string> nameCollection = new List<string>(); 


     foreach(Parent parent in parentCollection){ 
      nameCollection.Add(parent.Name); 
      foreach(Child child in parent.Children) 
       nameCollection.Add(child.Name); 

     } 

    } 
} 


public class Parent 
{ 
    public string Name = string.Empty; 
    public List<Child> Children = new List<Child>(); 
} 
public class Child 
{ 
    public string Name = string.Empty; 
} 

答えて

3

あなたは、サブコレクションを平らSelectManyを使用することができます。あなたは子を再帰的に生成するイテレータを実装する必要がある真の再帰(いくつかのレベル)があります。

編集:正しい順序で子供を持つために、働く醜い何か:

var all = parentCollection.Select(p=>new {Parent=p.Name, Name = ""}) 
      .Concat(parentCollection.SelectMany(p=>p.Children 
          .Select(c => new {Parent=p.Name, c.Name}))) 
      .OrderBy(o => o.Parent).ThenBy(o => o.Name) 
      .Select(o=> o.Name != "" ? o.Name : o.Parent); 
+0

コードは+1良いです。再帰についての批判は忌まわしいです - 私はそれに同意しません。 –

+0

ええ、私は少しそれを台無しにしました。私はfooがienumerableであるところで "yield return foo"を持つのが難しいと考えていました。いくつかのレベルがある場合は、親の子ツリーをトラバースするためにカスタムイテレータを実行する必要があります。 –

関連する問題