Grouping linq objects

I have an object object and poeple that have a group of properties that makes them belong to different groups. I want to get a List and put it in a GrouppedPeople object, which will have a List coll. One coll element contains only people from the same group.

So, if I had 3 people:

List<People>(){new People{Name="Test", Group = "Group1"}, new People{Name="SameGroup", Group = "Group1"}, new People{Name="Other", Group = "OtherGroup"}} 

I need to have a collection of 2 GrouppedPeople. First it will contain Test and SameGroup, and the second will contain Other (groupped by Group). I am trying to do this using linq.

I need results like List. GrouppedPeople is a class that has only one property of type List and all poeple from one group.

Ive come out with something like this:

 from oneGroup in mates group oneGroup by oneGroup.pGroupName into g select g; 

Works fine, but the result object is not strongly typed. And Id like to have List as the result. Is there any way to get this from this anonymous object type? Any other ways to get it all with linq and keep strong typing?

+4
source share
3 answers

This will return a list of anonymous object types:

 var result = (from oneGroup in mates group oneGroup by oneGroup.pGroupName into g select g).ToList(); 

But if you want to return objects of a certain type, you must create a new class with the required properties:

 public class MateGroup { public string Name {get;set;} } var result = (from oneGroup in mates group oneGroup by oneGroup.pGroupName into g select new MateGroup(){ Name = g.<field_name>}).ToList(); 

UPD:

According to your comment, try the following:

 var result = (from oneGroup in mates group oneGroup by oneGroup.pGroupName into g select new GrouppedPeople(){ People = g.ToList()}).ToList(); 
+4
source

What you get is IEnumerable<IGrouping<string, People>> . The IGrouping<TKey, TElement> has a Key containing (in your case, a string containing the value from the Group property in the People object), and you can list it to get elements that belong to the group:

 IEnumerable<IGrouping<string, People>> result = from oneGroup in mates group oneGroup by oneGroup.Group into g select g; foreach (IGrouping<string, People> grouping in result) { Console.WriteLine("Group: {0}", grouping.Key); foreach (People people in grouping) { Console.WriteLine(" - {0}", people.Name); } } 

Result (based on example data):

 Group: Group1 - Test - SameGroup Group: OtherGroup - Other 
+3
source

I prefer the common C # syntax for writing LINQ queries, the clearer the simple request form.

You can use the result selector to resolve the grouping result as a typed object.

 var resultList = mates .GroupBy(p => p.Group, (g, p) => new B() { Group = g, People = p.ToList() }) .ToList(); 

Full application code for the test console:

 class People { public string Name; public string Group; } class GroupedPeople { public string Group; public List<People> People; } class Program { static void Main(string[] args) { var mates = new List<People>() { new People{Name="Test", Group = "Group1"}, new People{Name="SameGroup", Group = "Group1"}, new People{Name="Other", Group = "OtherGroup"} }; var resultList = mates .GroupBy(p => p.Group, (g, p) => new GroupedPeople() { Group = g, People = p.ToList() }) .ToList(); } } 

To call GroupBy, two arguments are required:

  • p => p.Group - this lambda (anonymous method) used to return the grouping key

  • (g, p) => new GroupedPeople() { Group = g, People = p.ToList() }

    This lambda, used to create a GroupedPeople object based on the group parameters, the first argument is the grouping key, which is selected by the first lambda, the second argument is an enumeration with elements related to the current group.

+2
source

All Articles