2012-02-20 54 views
0

我需要平均3 IEnumerable集合并创建一个新的IEnumerable其结果如下:平均3个IEnumerables

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,结果2, result3将具有相同数量的元素(在本例中为4,但实际上它的范围可以为1500)。

  • 结果中的每个元素对应于结果的平均值,即,在result4集合中,第一个元素将是平均值1,3,2,它对应于result1中的第一个元素的平均值,result2,result3因此分别。

  • 所得收集应具有小数位(即通过为舍入成2

一个明显的答案是通过在集合的每个元素进行迭代和手动创建所得集合中的元素循环),但是我想避免它,因为结果将在每个集合中有近1500个元素,并且希望使用LINQ进行某种惰性评估。

请你帮助我一些指针?

干杯, -Mike

回答

7

如果您使用.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

想象一下斐波那契数列,每个数列中前1000个数列,即result1,result2和result3,每个数列都包含该系列。我相信你会使用result4的小数,然后,对吗? – Mike 2012-02-20 14:31:28

+0

@Mike:说实话,我不知道。在那里没有“单位”,真的......用“高度”和“薪水”等具体数字来说明更容易。你能把这个总和还给我们吗,而不是把它分成三份呢?这是相同的数据,毕竟只是缩放...... – 2012-02-20 14:38:36

0

实现此目的的一种方法是编写一个方法,该方法需要列表清单并执行必要的工作。喜欢的东西:然后

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

注:不包括为四舍五入@乔恩同样的理由;舍入是格式化/显示步骤。

+0

这并不是说这就需要所有数据都被拉入内存,而不需要它。它可以全部以流媒体的方式完成。 – 2012-02-20 14:37:51