Средние данные с одинаковым ключом в массиве словаря

1

У меня есть массив в С#, полный словарей.

Например:

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);
    }
}

Теперь я хочу найти все данные внутри массива "array" с ключом, который имеет конкретную дату, и Average "значения" для всех данных с этим ключом.

Другими словами, я хочу сделать что-то вроде этого:

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

(Я не очень хорошо разбираюсь в LINQ, поэтому вышеизложенное не имеет особого смысла...

Я просто хочу усреднить КАЖДЫЙ элемент внутри массива словаря "массив" с помощью ключа "myDate" и создать другой словарь/переменную, которая содержит средние значения.

Все массивы (массив [i]) имеют одинаковую длину.

Теги:
linq

4 ответа

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);
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 ;
}

И я готов поспорить, что последний работает значительно лучше, чем первый.

0

Я думаю, что вы хотите:

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

или

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

если не все словари будут иметь этот ключ.

Обратите внимание, что Dictionary<DateTime, int[]> сделает эти запросы намного проще (и займет меньше памяти, чем массив словарей).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню