2011-05-10 83 views
4

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

所以,如果我有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的属性的类,所有的元素都来自同一个组。

伊夫想出了这样的事情:

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

其工作正常,但结果对象不是强类型。并且Id喜欢将List作为结果。有没有办法从该匿名对象类型中获取它?任何其他方式来获得这一切与linq和保持强大的打字?

+0

你不会失去强打字。匿名类型与名义类型一样强类型。他们只是没有名字,就是这样。 – 2011-05-10 11:31:53

+0

你想要什么类型的列表?据我所见,您必须在现有代码中拥有IEnumerable >。 – Egor4eg 2011-05-10 11:34:30

+0

我想List 。 GrouppedPeople是一个包含List 的对象。 – 2011-05-10 13:08:27

回答

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(); 
+0

我想List 。 GrouppedPeople是一个包含List 的对象。我怎么才能得到它? – 2011-05-10 13:09:41

+0

请尝试我的更新回答 – 2011-05-10 13:27:32

+0

谢谢,帕维尔,对我来说工作得很好:-) – 2011-05-10 13:38:02

3

你将得到的是一个IEnumerable<IGrouping<string, People>>。该IGrouping<TKey, TElement>接口具有包含您通过分组(在你的情况下,包含在People对象从Group属性值的字符串)的值Key,你可以枚举它来获得属于该组的项目:

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

我更喜欢通用的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 - 这拉姆达(匿名方法)用于返回分组键

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

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

+0

Viacheslav,请问,请详细解释一下吗?我试图使用这个代码,它不适合我。什么是“g”?我在VS中获得以下错误:无法将lambda表达式转换为键入IEqualityComparer ,因为它不是委托类型。 – 2011-05-11 06:36:48

+1

你需要更多的细节?我不知道你是否需要关于lambda或扩展的信息? – 2011-05-11 13:08:03

+0

完美的作品,非常感谢。我希望我能标记2个答案作为答案。 – 2011-05-13 12:19:06