开发者

linq objects grouping

开发者 https://www.devze.com 2023-03-05 06:36 出处:网络
I have people object and poeple have property group that make them belong to different groups. I want to get List and put it in an object GrouppedPeople, in which there would be List coll. One coll el

I have people object and poeple have property group that make them belong to different groups. I want to get List and put it in an object GrouppedPeople, in which there would be List coll. One coll element contain only people that belong to 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 will contain Test and SameGroup, and second will contain Other (groupped by Group property). Im trying to do this using linq.

I need results to be of type List. GrouppedPeople is a class that have only one property of type List and all poeple are from the same group.

Ive came out with something like this:

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

Its working fine, but the result object is not strongly typed. And Id like to have List as the result. Is there a 开发者_如何学Goway to get it from that anonymous object type? Any other ways to get this all with linq and keep strong typing?


This will return List of anonymous type objects:

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

But if you want to return specific type objects you should create new class with 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 please try the following:

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


What you will get is an IEnumerable<IGrouping<string, People>>. The IGrouping<TKey, TElement> interface has a Key containing the value that you grouped by (in your case a string containing a value from the Group property in a People object), and you can enumerate over it to get the items belonging 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);
    }
}

Resulting output (based in your sample data):

Group: Group1
 - Test
 - SameGroup
Group: OtherGroup
 - Other


I prefer common C# syntax to write a LINQ query it's clearer than the simple query form.

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

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

Complete test console application code:

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

The GroupBy call require two arguments:

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

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

    That lambda used to create GroupedPeople object based on group parameters, first argument is a grouping key that selected by first lambda, second argument is enumeration with items related to the current group.

0

精彩评论

暂无评论...
验证码 换一张
取 消