Mike
Mike

Reputation: 3284

Average of 3 IEnumerables

I need to average 3 IEnumerable collection and create a new IEnumerable with the result as follows:

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.

An obvious answer is to iterate through each element in the collections and create the elements in the resultant collection manually (i.e via a for loop), however I want to avoid it as the results will have close to 1500 elements in each collection and would like to do some sort of lazy evaluation using LINQ.

Please can you help me with some pointers?

Cheers, -Mike

Upvotes: 0

Views: 114

Answers (2)

Jamiec
Jamiec

Reputation: 136134

One way to achieve this is to write a method which takes a list of lists, and does the necessary work. Something like:

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

Usage would then be

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

Live example: http://rextester.com/IGOSE98291

NB: Not included rounding for the same reason @Jon mentioned; rounding is a formatting/display step.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1502016

If you're using .NET 4, you can use Enumerable.Zip to good effect here:

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

This won't do any rounding - that would normally be more appropriate for a formatting step. Note that the values can only end with 0, 0.33, or 0.67 anyway, as you're only dividing by 3. Here I've used double but another option would be to use decimal - it depends on what the values really mean.

Upvotes: 7

Related Questions