C# Linq GroupBy/具有元组键的字典的聚合

C# Linq GroupBy/具有元组键的字典的聚合,c#,linq,dictionary,C#,Linq,Dictionary,我有一个字典,它的键是由两个对象(Object1和Object2)、一个DateTime和一个Enum组成的四部分元组。字典中存储的值是Object3类型的对象。Object3对象包含一个整数值属性。假设我们可以通过GetIntValue()方法访问它。(这是 这是一个假设性的例子;让我们不要详细讨论将四部分元组作为键是否是一个好主意!) 所以字典看起来像这样: 字典我的字典 键元组的DateTime部分以15分钟为增量。我希望将键聚合到天级别,并对从GetIntValue()获得的int值求和

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

所以字典看起来像这样:

字典我的字典

键元组的DateTime部分以15分钟为增量。我希望将键聚合到天级别,并对从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

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

假设您可以将
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()));

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

为什么要使用元组呢?您可能应该创建一个类,不要告诉我这是因为您不想覆盖get hashcode,并等于。(这是一个假设的例子;让我们不要详细讨论将四部分元组作为键是否是一个好主意!)时间是连续的,你只想按天分组,还是时间是随机的,你想把总和加起来等于24小时。你如何创建一个具有特定值的
Object3
。你是将它传递给它的构造函数还是有一个可以设置的属性。如果它是一个方法,那么Linq代码将是混乱的。时间不是顺序的ntial。我只想按日期分组,添加value object中的所有int-value属性。非常感谢!这似乎奏效了。(我自学了linq这方面的知识,所以对我来说并不总是直观!)