我需要平均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之前)。
< / LI>结果中的每个元素对应于结果的平均值,即在result4集合中,第一个元素的平均值为1,3,2,它对应于result1,result2中第一个元素的平均值,结果3分别因此而来。
结果集合的小数位应舍入为2。
一个明显的答案是迭代集合中的每个元素并手动创建结果集合中的元素(即通过for循环),但是我想避免它,因为结果将在每个集合中具有接近1500个元素并希望使用LINQ进行某种懒惰的评估。
请你帮忙指点一下吗?
干杯, -Mike
答案 0 :(得分: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
- 它取决于关于价值观的真正含义。
答案 1 :(得分: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
注意:不包括舍入因为@Jon提到的相同原因;舍入是格式化/显示步骤。