如何在Linq中对组内的元素进行分组

时间:2013-06-25 17:02:28

标签: c# linq

我有一个Employee Collection,我希望以这样一种方式进行过滤,即只应过滤前两列,并且应附加第三列值,最终结果应该在一行中

以下是我的代码

List<Employe> Employeecollection = new List<Employe>();

        Employeecollection.Add(new Employe("Employee1", "Dept1","Language1"));
        Employeecollection.Add(new Employe("Employee2", "Dept2", "Language2"));
        Employeecollection.Add(new Employe("Employee3", "Dept3", "Language3"));
        Employeecollection.Add(new Employe("Employee3", "Dept3", "Language3"));
        Employeecollection.Add(new Employe("Employee1", "Dept1", "Language2"));

        foreach (Employe item in Employeecollection.GroupBy(x => new { fName = x.EmpName, lName = x.EmpDept, mName = x.KnownLanguages }).Select(g => g.First()))
        {
            Console.WriteLine(item.EmpName + "   " + item.EmpDept + " " + item.KnownLanguages);
        }

但我想显示如下结果

Employee1 Dept1 Language1,Language2
Employee2 Dept2 Language2
Employee3 Dept3 Language3

2 个答案:

答案 0 :(得分:5)

按名称和部门对员工进行分组,然后为每位员工选择已知语言的连接字符串:

from e in Employeecollection
group e by new { e.Name, e.EmpDept } into g
select new {
   g.Key.Name,
   g.Key.EmpDept,
   Languages = String.Join(",", g.Select(x => x.KnownLanguages))
}

如果您希望结果为单行,请执行以下投影:

select String.Format("{0} {1} {2}", 
    g.Key.Name, g.Key.EmpDept, String.Join(",", g.Select(x => x.KnownLanguages)))

BTW我认为它是一个奇怪的属性名KnownLanguages,用于保存单一语言的属性

答案 1 :(得分:2)

您不希望在KnownLanguages上进行分组。它不应该包含在您的组选择器中。组选择器应该为组中的所有项选择所有想要相同的东西。

您还需要更改打印结果的方式。通过Key获取组中每个项目的公共值,通过迭代组本身获取其他值。

var query = Employeecollection.GroupBy(x => new
{
    x.EmpName,
    x.EmpDept
};

foreach (var group in query)
{
    string languages = string.Join(", ", 
        group.Select(employee => employee.KnownLanguages)
        .Distinct());
    Console.WriteLine(group.Key.EmpName + "   " + group.Key.EmpDept + " " 
        + languages;
}