2

I have an object which looks like this:

Tree {
    String Name;
    Int ID;
    List<SubObjects> SubObjects
}

SubObjects {
    int Level;
    string Name;
}

I have information coming over in the following form of List<Output> where Output is:

Output {
    String TreeName;
    Int TreeID;
    Int SubObjectLevel;
    String SubObjectName;
}

Essentially, the Tree is represented in following format

Tree1 TreeID1 Level1 SubObject1

Tree1 TreeID1 Level2 SubObject2

Tree1 TreeID1 Level3 SubObject3

Tree1 TreeID1 Level1 SubObject4

I want to write a LINQ query to populate Tree and I am stuck at GroupBy. It is a very basic question but I am in process of learning LINQ, any help will be much appreciated.

Thanks!

EDIT:

Here is my code so far

var trees =
    from o in output
    select new Tree {
        Name = o.TreeName,
        ID   = o.TreeID,
        SubObjects = //somehow group them
    }

I have also tried

var trees =
    from o in output
    group o in o.TreeID into levels
    select new Tree {
        Name = //at this point o.TreeName is not available
    }
Vinay Pandey
  • 1,129
  • 3
  • 16
  • 33
  • 1
    Please show us what code you have so far. – magnattic Feb 28 '13 at 00:30
  • Also, what you have is not really a tree. Its basically a class that holds a List of objects. See [Wiki](https://en.wikipedia.org/wiki/Tree_(data_structure)) for what a tree is and [Tree data structure in C#](http://stackoverflow.com/questions/66893/tree-data-structure-in-c-sharp) for some tips how to build an actual tree. – magnattic Feb 28 '13 at 00:34
  • I agree, it's not a tree. I should have been careful with my forming of question. I am basically trying to populate a UI object which will have a Tree representation that's why I used that terminology. – Vinay Pandey Feb 28 '13 at 00:37

1 Answers1

5

So GroupBy takes a flat list and produces a set of smaller IGrouping based on a defined key - in this case, you want the key to be the "Tree", since that's the common element:

var sourceOutputs = <...get outputs list...>;

var query =
     // for each <Output> thingy...
     from outputThing in sourceOutputs

And here I'll pause, since you have many options here - we can group by tree ID, by Tree Name, etc - I'll group by both ID and Name:

var query =
     // for each <Output> thingy...
     from outputThing in sourceOutputs
     // group them by Tree ID + Tree name
     group outputThing by 
         new { ID = outputThing.TreeID, Name = outputThing.TreeName } 
     into byTree
     // So now we can transform these groups of <Output> into a tree
     select new Tree
     {
         ID = byTree.Key.ID,
         Name = byTree.Key.Name,
         // And now the sub objects:
         // what 'byTree' actually is => a key (ID + name), 
         // and an enumerable of <Output> objects that match that key
         SubObjects = 
           (
               from matchedThingy in byTree
               select new SubObject() 
               { 
                   Level = matchedThingy.SubObjectLevel,
                   Name = matchedThingy.SubObjectName
                }
           ).ToList()
     };
JerKimball
  • 16,584
  • 3
  • 43
  • 55