我有一个班级:
public class PointD
{
public double X
{ get; set; }
public double Y
{ get; set; }
public PointD(double x, double y)
{
X = x;
Y=y;
}
//operator for +,-, * and / are overridden
}
给定list<PointD>
,如何使用LINQ获得平均值?一个for
循环等价物将是这样的:
double xx, yy;
for ( int i=0; i< ptlist.Count; i++)
{
xx+=ptlist[i].X;
yy+=ptlist[i].Y;
}
return new PointD(){X=xx, Y=yy};
您只能使用任何内置 LINQ功能。您无法定义负责此功能的扩展程序。
有什么想法吗?
编辑:当然,在合并之前,您可以使用两个单独的Sum
扩展方法对X和Y组件求和。但这不是我想要的。我想要的是一个完成工作的单一查询/方法
答案 0 :(得分:13)
Aggregate
功能在这里会派上用场。
var sum = list.Aggregate((acc, cur) => acc + cur);
var average = list.Aggregate((acc, cur) => acc + cur) / list.Count;
确保您为/
和PointD
类型定义int
运算符,这应该可以胜任。
注意:我不太确定你是否想要这里的总和或平均值(你的问题对此有些模棱两可),但我已经包含了两者的例子。
答案 1 :(得分:6)
您需要使用Aggregate
方法,以便提供自己的聚合函数(Sum
只是此方法的一个方便的专用案例)。类似的东西:
points.Aggregate(new PointD(0, 0), (a, p) => a + p);
我知道你说你不想要任何其他方法定义,但如果这是一个常见的操作,我倾向于为此编写扩展方法,即
public static PointD Sum(this IEnumerable<PointD> source)
{
return source.Aggregate(new PointD(0, 0), (a, p) => a + p);
}
因为能够写得更具可读性:
points.Sum();
答案 2 :(得分:0)
[Fact]
public void CanAddManyPointDs()
{
var points = new[]{
new PointD( 1,1),
new PointD( 2,3),
new PointD( 3,4),
};
var result = points.Aggregate((p1, p2) => new PointD(p1.X + p2.X, p1.Y + p2.Y));
Assert.Equal(result.X,6);
Assert.Equal(result.Y,8);
}