tags:

views:

398

answers:

2

Hi,

Is there a LINQ way to accomplish this? Any help is greatly appreciated.

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;
}
+1  A: 

You can use SelectMany which flattens sub collections :

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

Note this will only work with one depth of parent/child relationship. Yo have true recursion (several levels) you'd have to implement an iterator that yields the children recursively.

Edit: to have the children in the correct order, something ugly that works:

 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);
Yann Schwartz
Code is good +1. Remark about recursion is wierd - I don't agree with that.
David B
Yeah I did mess it up a bit. I was thinking about the difficulty to have "yield return foo" where foo is an ienumerable. You'd have to go through a custom iterator to traverse the parent children tree if there are several levels.
Yann Schwartz
A: 

Hi

Thanks a lot for your response.

Output for the above LINQ expression is P1, P2, C1, C2, C3, C4. I would like to have an output something like P1, C1, C2, P2, C3, C4.

I updated my code to do just that
Yann Schwartz