【问题标题】:Group a list of anonymous type objects using linq and lambda使用 linq 和 lambda 对匿名类型对象列表进行分组
【发布时间】:2014-03-06 23:56:11
【问题描述】:
 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=&gt; x.Age); 之类的方法,但没有成功。

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

【问题讨论】:

    标签: c# linq list lambda anonymous-types


    【解决方案1】:

    您使用直接对象的方法不起作用,因为对象没有 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,因为您的名称中有重复项:)

    【讨论】:

    • 为了将 Student 对象添加到列表中,我们再次使用 new Student { Name = "A", Age = 28, Height = 175 }?
    • 是的。或者,如果您愿意,可以为该类添加构造函数。
    • ,构造函数的例子?
    • @burhan 我的意思是最简单的构造函数 :) 更新示例以防万一
    • @burhan:因为这里讨论的 GroupBy 重载是 msdn.microsoft.com/en-us/library/bb549393(v=vs.110).aspx 。第二个参数的类型为Func&lt;TKey, IEnumerable&lt;TSource&gt;, TResult&gt;。这意味着它有两个输入参数和输出。在这种情况下,id 是键,xs 是分组元素。 id 没有被使用,但它必须存在,否则编译器会抱怨它找不到正确的重载,或者它可能会将它与 http://msdn.microsoft.com/en-us/library/bb534304(v=vs.110).aspx 混淆(我不太确定哪个没有尝试)。
    【解决方案2】:

    您可以执行以下操作:

     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(),但我正在向您展示如果您想用它做任何其他列表的事情)。这样做的好处是ToList 是一种通用方法,可以从它正在处理的可枚举中推断出类型是什么,在这种情况下是匿名类型的可枚举。

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

    至于创建以名称为键、高度为值的字典 - 你不能。字典需要有唯一的键,并且您在这里有多个具有相同名称的项目,因此尝试执行 ToDictionary() 是行不通的。

    您可以尝试使用ToLookup(),它将获取可枚举匹配值的键(类似于 group by,但更容易查找)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      相关资源
      最近更新 更多