这可能非常简单,但我的尝试(在 Intellisense 和 MSDN 的指导下)都没有成功。
如果我有一个包含 3 个 double 的类,我怎样才能得到这些列表的平均值?
class DataPoint
{
public int time;
public int X;
public int Y;
public int Z;
// Constructor omitted
}
class Main
{
List<DataPoint> points = new List<DataPoint>();
// Populate list
DataPoint averagePoint = points.Average(someMagicHere);
}
我希望 averagePoint
包含 time
、x
、y
和 z
值是构成列表的元素的这些属性的平均值。我该怎么做呢?我正在努力解决的问题是(我认为)someMagicHere
,但我可能一开始就使用了完全错误的方法。
最佳答案
问题不是很清楚,但听起来你想要的是一个新点 P,其中 P.X 是列表中点的所有 X 坐标的平均值,依此类推,是吗?
解决此类问题的一般方法是将其分解:
首先将点列表转换为四个整数列表。
var times = from p in points select p.Time;
var xs = from p in points select p.X;
... and so on ..
或者,如果您更喜欢这种表示法:
var times = points.Select(p=>p.Time);
现在你可以平均这些:
double averageTime = times.Average();
double averageX = xs.Average();
... and so on ...
现在您有了四个值( double 值),您可以使用它们来构建平均点。当然,您必须使用您喜欢的任何舍入将 double 转换为整数。
但是,有一个特殊版本的“Average”,它将 Select 和 Average 合并为一个操作。你可以说
double averageTime = points.Average(p=>p.Time);
并一步完成投影和平均值。
正如一些人指出的那样,这种方法的缺点是序列被枚举了四次。这可能没什么大不了的,因为它是一个内存列表,但如果它是一个昂贵的数据库查询,则可能更重要。
另一种方法是在您的 DataPoint 类上定义加法运算符(如果通常对两点求和有意义,但它可能没有意义)。一旦有了加法运算符,对所有点求和就很简单了。
无论是否定义加法运算符,都可以使用Aggregate计算所有点的总和,然后将总和的四个字段除以点数。
DataPoint sum = points.Aggregate(
new DataPoint(0, 0, 0, 0),
(agg, point)=> new DataPoint(agg.time + point.time, agg.x + point.x, ... ));
或者,如果您有运算符(operator),只需:
DataPoint sum = points.Aggregate(
new DataPoint(0, 0, 0, 0),
(agg, point)=> agg + point);
现在您有了总和,因此计算平均值很简单。
关于c# - 如何编写扩展函数以返回自定义类型的平均值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6298763/