字典数组中具有相同键的平均数据

时间:2014-05-27 19:58:07

标签: c# linq

我在c#中有一个充满字典的数组。

例如:

Dictionary<DateTime, int>[] array = new Dictionary<DateTime, int>[numberOfArrays];

然后我用这样的键和值填充它们:

for(int i = 0; i<numberOfArrays; i++)
{
    array[i] = new Dictionary<DateTime, int>(); 

    foreach (var date in mySourceOfData)
    {     
       array[i].Add(date, value);
    }
}

现在我想找到我的数组中的所有数据&#34; array&#34;使用具有特定日期的密钥,并平均&#34;值&#34;对于具有该密钥的所有数据。

换句话说,我想做这样的事情:

array.Value.Average(x=>x.key= myDate);

(我根本不擅长LINQ所以上面的内容可能没什么意义......

我只想平均字典数组中的每个元素&#34;数组&#34;用钥匙&#34; myDate&#34;并生成另一个包含平均值的字典/变量。

所有数组(array [i])的长度都相同。

4 个答案:

答案 0 :(得分:2)

您可以从所有词典中选择所有KeyValuePairs。然后按密钥(即按日期)对它们进行分组,并将组转换为另一个字典,其中日期为每个组的关键和平均值(即来自分组日期的所有KeyValuePairs):

var averageByDate = array.SelectMany(d => d)
                         .GroupBy(kvp => kvp.Key)
                         .ToDictionary(g => g.Key,
                                       g => g.Average(kvp => kvp.Value));

然后获得特定日期的平均值将如下所示:

var average = averageByDate[someDate];

答案 1 :(得分:1)

var avg = array.SelectMany(d => d)
    .Where(kvp => kvp.Key == myDate)
    .Average(kvp => kvp.Value);

答案 2 :(得分:0)

我认为你想要的是:

array.Average(x=>x[myDate]);

array.Where(d => d.ContainsKey(myDate)).Average(x=>x[myDate]);

如果不是所有字典都有该密钥。

请注意,Dictionary<DateTime, int[]>会使这些查询更容易(并且比字典数组占用更少的内存)。

答案 3 :(得分:0)

虽然你可以使用Linq,比如

public decimal MeanForParticularDate( DateTime desired , Dictionary<DateTime,int>[] collection )
{
  decimal mean = collection
                 .SelectMany(
                   entry => entry
                            .Where(  x => x.Key == desired  )
                            .Select( x => (decimal) x.Value )
                   )
                 .Average()
                 ;
  return mean ;
}

我认为这不比直接(更容易调试)实现更简洁或易懂:

public decimal MeanForParticularDate( DateTime desired , Dictionary<DateTime,int>[] collection )
{
  decimal n   = 0 ;
  decimal sum = 0 ;

  foreach( Dictionary<DateTime,int> dict in collection )
  {
    int value ;
    bool found = dict.TryGetValue( desired , out value ) ;

    if ( !found ) continue ;

    ++n ;
    sum += value ;

  }

  decimal mean = sum/n ;
  return mean ;
}

而且我愿意打赌,后者的表现明显优于前者。