Среднее из 3 IEnumerables - PullRequest
       3

Среднее из 3 IEnumerables

0 голосов
/ 20 февраля 2012

Мне нужно в среднем 3 IEnumerable коллекции и создать новый IEnumerable с результатом следующим образом:

var result1 = GetResult1()//Returns an enumerable collection having elements 1,2,3,4

var result2 = GetResult2()//Returns an enumerable collection having elements 3,4,2,6

var result3 = GetResult3()//returns an enumerable collection having elements 2,5,1,6

//I need to create a collection which has the averages of the above results as below:

var result4 = GetResult4()//Should return 2.00,3.67,2.33,5.33.
  • Каждый результат будет иметь одинаковое количество элементов, т.е. result1, result2, result3 будет иметь такое же количество элементов (в данном случае 4, но на самом деле оно может варьироваться до 1500).

  • Каждый элемент в результате соответствует среднему значению результатовт.е. в коллекции result4 первый элемент будет иметь среднее значение 1,3,2, что соответствует среднему значению первого элемента в result1, result2, result3 соответственно и, следовательно, вперед.

  • результирующая коллекция должна иметь десятичные разряды, округленные до 2.

Очевидный ответ - перебирать каждый элемент в коллекциях и создавать элементы в результирующей коллекции вручную (т.е. через цикл for), однако я хочу избежать этого, так как результаты будут иметь около 1500 элементов в каждой коллекции и хотели бы сделать что-то вроделенивый анализ с использованием LINQ.

Пожалуйста, вы можете помочь мне с некоторыми указателями?

Ура, -Майк

Ответы [ 2 ]

7 голосов
/ 20 февраля 2012

Если вы используете .NET 4, вы можете использовать Enumerable.Zip для хорошего эффекта здесь:

var averages = result1.Zip(result2, (x, y) => x + y)
                      .Zip(result3, (xy, z) => (xy + z) / 3.0d)
                      .ToList();

Это не будет делать никакого округления - это обычно было бы более подходящим для шага форматирования . Обратите внимание, что значения в любом случае могут заканчиваться только 0, 0,33 или 0,67, так как вы делите только на 3. Здесь я использовал double, но другой вариант будет использовать decimal - это зависит от того, какие значения действительно значит.

0 голосов
/ 20 февраля 2012

Один из способов достижения этого - написать метод, который берет список списков и выполняет необходимую работу.Что-то вроде:

 private static IEnumerable<double> AverageOfLists(params IEnumerable<double>[] values)
 {
     var lists = values.Select(v => v.ToList()).ToArray();

     for(var i=0;i<lists[0].Count;i++)
     {
         var sum = 0.0;
         for(var j=0;j<lists.Length;j++)
         {
             sum+= lists[j][i];
         }
         yield return sum/lists.Length;
     }
 }

Использование будет тогда

var result4 = AverageOfLists(result1,result2,result3);

Живой пример: http://rextester.com/IGOSE98291

Примечание: не включено округление по той же причине, о которой упоминал @Jon;округление является шагом форматирования / отображения.

...