linq对象分组

时间:2011-05-10 11:26:33

标签: linq group-by linq-to-objects

我有人物和人物有属性组,使他们属于不同的群体。 我想获取List并将其放在一个对象GrouppedPeople中,其中会有List coll。一个coll元素只包含属于同一组的人。

所以,如果我有3个人:

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

我需要有2个GrouppedPeople的集合。第一个将包含Test和SameGroup,第二个将包含Other(由Group属性分组)。我试图用linq做到这一点。

我需要结果为List类型。 GrouppedPeople是一个只有一个List类型属性的类,所有的poeple都来自同一个组。

我出来了这样的事情:

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

它工作正常,但结果对象没有强类型。并且我喜欢将List作为结果。有没有办法从匿名对象类型中获取它?还有其他任何方法可以通过linq获得这一切并保持强力输入吗?

3 个答案:

答案 0 :(得分:4)

这将返回匿名类型对象列表:

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

但是如果要返回特定类型对象,则应创建具有所需属性的新类:

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:

根据您的评论,请尝试以下操作:

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

答案 1 :(得分:3)

您将获得IEnumerable<IGrouping<string, People>>IGrouping<TKey, TElement>接口的Key包含您按其分组的值(在您的情况下是一个字符串,其中包含Group对象中People属性的值)可以枚举它以获取属于该组的项目:

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

结果输出(基于您的样本数据):

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

答案 2 :(得分:2)

我更喜欢使用常见的C#语法来编写LINQ查询,它比简单的查询表单更清晰。

您可以使用结果选择器将分组结果解析为类型化对象。

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

完整的测试控制台应用程序代码:

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

GroupBy调用需要两个参数:

  1. p => p.Group - 用于返回分组键的lambda(匿名方法)

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

    lambda用于根据组参数创建GroupedPeople对象,第一个参数是由第一个lambda选择的分组键,第二个参数是枚举,其中包含与当前组相关的项目。