我该如何“合并”?多个字典组成一个“aggregate"在c#

本文关键字:一个 aggregate quot 合并 字典 | 更新日期: 2023-09-27 18:12:27

我有以下场景:

函数GetDict()返回一个Dictionary<double, double>对象,并在循环中被调用若干次(此次数由用户指定)。返回的Dictionary总是保证包含相同的键集(我现在假设这样做是为了简单)。

我的目标是最终得到每个键返回的所有值的平均值:

public Dictionary<double, double> CalculateAveragePerKey(int N)
{
    var aggregateDict = new Dictionary<double, double>();
    for(int i=0; i < N; i++)
    {
        var returnedDict = GetDict();
        // aggregateDict -- how to calculate an average of values for each key?
    }
    return aggregateDict;
}
public Dictionary<double, double> GetDict()
{
    var newDict = new Dictionary<double, double>();
    // populate the newDict, always guaranteed (assumed for simplicity)
    // to contain the same set of keys ...
    return newDict;
}

因此,如果N=3并且在循环中,返回的Dictionary包含键10.0的值1.0, 2.33.0,在末尾aggregateDict应该包含键10.0的值2.1

如果这不是解决这类问题的最佳数据结构或方法,我绝对可以重构我的代码,使用其他数据结构或方法。我只是在寻找最有效的方法。

我该如何“合并”?多个字典组成一个“aggregate"在c#

您可以修改代码以分两步计算平均值:

  • 当你在循环中调用GetDict()时,遍历它的键,并将值添加到aggregateDict的值
  • 当循环结束时,再次遍历数值,并除以N

你也可以在循环中用GetDict()的值除以N,这取决于你在GetDict()中得到的值的分布。

你也可以在LINQ中这样做,而不使用循环,像这样:
var avg = Enumerable
    .Range(0, N)
    .SelectMany(n => GetDict())
    .GroupBy(p => p.Key)
    .ToDictionary(
            g => g.Key
        ,   g => g.Sum(p => p.Value) / g.Count()
        );

注意,在使用double作为字典键时需要非常小心,因为浮点类型本质上是不精确的。因此,您可能会看到两个非常接近的数字映射到不同的字典键。