使用linq和lambda对匿名类型对象的列表进行分组

时间:2014-03-06 23:56:12

标签: c# linq list lambda anonymous-types

 List<object> Students = new List<object>() {
    new { Name = "A", Age = 28, Height = 175 },
    new { Name = "B", Age = 29, Height = 176 },
    new { Name = "C", Age = 30, Height = 177 },
    new { Name = "D", Age = 31, Height = 178 },
    new { Name = "A", Age = 32, Height = 179 },
    new { Name = "E", Age = 33, Height = 180 },
    new { Name = "A", Age = 34, Height = 181 },
    new { Name = "F", Age = 35, Height = 182 },
    new { Name = "B", Age = 36, Height = 183 }
};

1)如何按年龄对上述列表进行分组?

我尝试了类似var test = Students.GroupBy(x=> x.Age);的内容,但它没有用。

2)我想创建一个字典,其名称为Key,高度为Value。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:2)

使用直接对象的方法不起作用,因为对象没有Age属性。最好使用具有Name,Age和Height属性的预定义类。它将更具可读性和类型安全性......

class Student
{
   public string Name {get; set;}
   public int Age {get; set;}
   public int Height {get; set;}

   public Student() {} //you would need parameterless constructor to use "new Student {...}"
   public Student(string name, int age, int height)
   {
      Name = name;
      Age = age;
      Height = height;
   }
}
var Students = new List<Student>() 
                   { 
                      new Student { Name = "A", Age = 29, Height = 175 },  //using initializer
                      new Student("B", 30, 176), //using constructor
                      ... 
                   };

但如果不可能 - 你可以随时使用dynamic。像这样:

List<dynamic> Students = new List<dynamic>() 
                             { 
                                new { Name = "A", Age = 28, Height = 175 }, 
                                ...
                             };
var test = Students.GroupBy(x=> x.Age);

和词典 - 使用ToDictionary

var test = Students.ToDictionary(x=> x.Name, x => x.Height);

但是您可能想尝试ToLookup,因为您的姓名中有重复项:)

答案 1 :(得分:1)

您可以执行以下操作:

 var Students = new []{
    new { Name = "A", Age = 28, Height = 175 },
    new { Name = "B", Age = 29, Height = 176 },
    new { Name = "C", Age = 30, Height = 177 },
    new { Name = "D", Age = 31, Height = 178 },
    new { Name = "A", Age = 32, Height = 179 },
    new { Name = "E", Age = 33, Height = 180 },
    new { Name = "A", Age = 34, Height = 181 },
    new { Name = "F", Age = 35, Height = 182 },
    new { Name = "B", Age = 36, Height = 183 }
}.ToList();

var groupedStudents = Students.GroupBy(x=>x.Age);

关键的区别在于我创建了一个匿名列表(我实际上并不需要.ToList()但是我告诉你如果你想用它做任何其他List的东西)。这样做的好处是ToList是一个通用的方法,可以从它正在处理的可枚举中推断出类型是什么,在这种情况下是可枚举的匿名类型。

当然,很多时候你可能最好只创建一个Student对象,而不是使用匿名对象。

至于创建一个名称为key,height为value的字典 - 你不能。字典需要有唯一的密钥,并且您在此处有多个具有相同名称的项目,因此尝试ToDictionary()它将无效。

您可以尝试使用ToLookup()来获取一系列匹配值的关键字(类似于分组但更容易查找)。