Linq GroupBy/聚合键为元组的字典

本文关键字:元组 字典 GroupBy Linq | 更新日期: 2023-09-27 18:06:17

我有一个Dictionary,它的Key是由两个对象(Object1和Object2),一个DateTime和一个Enum组成的四部分元组。Dictionary中存储的值是Object3类型的对象。Object3对象包含一个属性,它是一个整数值。假设我们可以通过GetIntValue()方法访问它。(这是假设性的例子;让我们不要纠结用四部分元组作为键是否是个好主意!)

所以字典看起来是这样的:

Dictionary<Tuple<Object1, Object2, DateTime, Enum1>, Object3> myDictionary

键元组的DateTime部分以15分钟为单位给出。我想将键聚合到DAY级别,并将从GetIntValue()获得的int值求和。我知道我可以通过编程方式做到这一点,是否与循环,创建其他字典/列表等,这可能会更好/更快,但我想知道这是否可以在单行LINQ语句中做到?

字典中的示例数据可能看起来像:

Object1 | Object2   | Datetime          | Enum  | Object3.GetIntValue()
o1      | p1        | 09/07/2016 8:00AM | Type1 | 30
o1      | p1        | 09/07/2016 8:15AM | Type1 | 20
o1      | p1        | 09/07/2016 8:30AM | Type1 | 10
o2      | p2        | 09/07/2016 8:00AM | Type1 | 0
o2      | p2        | 09/07/2016 8:15AM | Type1 | 10
o2      | p2        | 09/07/2016 8:30AM | Type1 | 5
o1      | p1        | 09/08/2016 8:00AM | Type1 | 0
o1      | p1        | 09/08/2016 8:15AM | Type1 | 30
o1      | p1        | 09/08/2016 8:30AM | Type1 | 5
o2      | p2        | 09/08/2016 8:00AM | Type1 | 0
o2      | p2        | 09/08/2016 8:15AM | Type1 | 0
o2      | p2        | 09/08/2016 8:30AM | Type1 | 1

期望输出为:

Object1 | Object2   | Date part of Datetime | Enum  | Sum of Object3.GetIntValue()
o1      | p1        | 09/07/2016 12:00AM    | Type1 | 60
o2      | p2        | 09/07/2016 12:00AM    | Type1 | 15
o1      | p1        | 09/08/2016 12:00AM    | Type1 | 35
o2      | p2        | 09/08/2016 12:00AM    | Type1 | 1

输出容器可以是字典或其他可枚举结构体

Linq GroupBy/聚合键为元组的字典

假设您可以将int的值传递给Object3的构造函数,它将看起来像这样:

var byDay = originalDictionary.GroupBy(
        kvp => Tuple.Create(
            kvp.Key.Item1, 
            kvp.Key.Item2, 
            kvp.Key.Item3.Date, 
            kvp.Key.Item4))
    .ToDictionary(
         grp => grp.Key, 
         grp => new Object3(grp.Sum(kvp => kvp.Value.GetIntValue())));

或者如果您不需要它映射到Object3,而只是一个int,您可以将最后一个lambda更改为

grp => grp.Sum(kvp => kvp.Value.GetIntValue())

如果你只需要日期和值,你可以这样做,否则你可以使用@juharr的答案

 myDictionary.GroupBy(x => x.Datetime.Date)
             .ToDictionary(k => k.Key, 
                           v => v.Value.Sum(x => x.Object3.GetIntValue()));

这应该按日期对所有数据进行分组,然后它将创建一个字典,其中包含日期到求和值