使用LINQ获取具有自定义对象的列表的总和/平均值

我上课了:

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 ,如何使用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函数。 您无法定义负责此function的扩展。

任何的想法?

编辑:当然,在合并它们之前,您可以使用两个单独的Sum扩展方法对X和Y组件求和。 但这不是我想要的。 我想要的是一个完成这项工作的单一查询/方法

Aggregate函数在这里会派上用场。

 var sum = list.Aggregate((acc, cur) => acc + cur); var average = list.Aggregate((acc, cur) => acc + cur) / list.Count; 

只要确保你为类型PointDint定义了/运算符,这应该可以胜任。

注意:我不太确定你是否想要这里的总和或平均值(你的问题对此有些模棱两可),但我已经包含了两者的例子。

您需要使用Aggregate方法,以便您可以提供自己的聚合函数( Sum只是此方法的一个方便的特殊情况)。 就像是:

 points.Aggregate(new PointD(0, 0), (a, p) => a + p); 

我知道你说你不想要任何额外的方法定义,但如果这是一个常见的操作,我倾向于为此编写一个扩展方法,即

 public static PointD Sum(this IEnumerable source) { return source.Aggregate(new PointD(0, 0), (a, p) => a + p); } 

因为它能够写得更具可读性:

 points.Sum(); 
  [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); }