如何编写扩展函数来返回自定义类型的平均值?
这可能非常简单,但我的尝试(在 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
,但我可能一开始就使用了完全错误的方法。
This is probably very simple, but my attempts (guided by Intellisense and MSDN) have all been off the mark.
If I have a class which contains 3 double, how can I get the average of a list of these?
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);
}
I want averagePoint
to contain time
, x
, y
& z
values that are the average of these properties of the elements that make up the list. How do I do this? The bit I'm struggling with is (I think) someMagicHere
, but I could be using completely the wrong approach to begin with.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题并不完全清楚,但听起来您想要的是一个新点 P,其中 PX 是列表中所有点的 X 坐标的平均值,依此类推,是吗?
解决此类问题的一般方法是将其分解:
首先将点列表转换为四个整数列表。
或者,如果您更喜欢这种表示法:
现在您可以对它们进行平均:
现在您有了四个值(作为双精度值),您可以使用它们来构造平均点。当然,您必须使用您喜欢的任何舍入方式将双精度数转换为整数。
然而,有一种特殊版本的“平均”,它将选择和平均合并为一个操作。 您可以一步一步说出来
对于预测和平均值,
并做到这一点。正如一些人所指出的,这种方法的缺点是序列被枚举四次。这可能不是什么大问题,因为它是一个内存列表,但如果它是一个昂贵的数据库查询,则可能更重要。
另一种方法是在 DataPoint 类上定义加法运算符(如果一般来说对两个点求和是有意义的,但实际上可能没有)。一旦有了加法运算符,计算所有点的总和就很简单了。
无论是否定义加法运算符,都可以使用 Aggregate 来计算所有点的总和,然后将总和的四个字段除以点数。
或者,如果您有运算符,只需:
现在您有了总和,因此计算平均值很简单。
The question is not entirely clear, but it sounds like what you want is a new point P where P.X is the average of all the X coordinates of the points in the list, and so on, yes?
The general way to solve a problem like this is to break it down:
First transform the list of points into four lists of integers.
Or, if you prefer this notation:
Now you can average those:
and now you have your four values -- as doubles -- that you can use to construct the average point. Of course you'll have to convert the doubles to integers, using whatever rounding you prefer.
However, there is a special version of "Average" which combines the Select and the Average into one operation. You can just say
and do it in one step for both the projection and the average.
The down side of this approach, as some have noted, is that the sequence is enumerated four times. Which is probably not a big deal, since it is an in-memory list, but might be more of a big deal if it were an expensive database query.
Another approach would be to define the addition operator on your DataPoint class (if in general it makes sense to sum two points, which it might not). Once you have an addition operator, making the sum of all the points is straightforward.
Whether you define an addition operator or not, you can use Aggregate to compute the sum of all the Points, and then divide the four fields of the sum by the number of points.
or, if you have the operator, simply:
And now you have the sum, so computing the average is straightforward.
好吧,看来您需要依次取每个投影的平均值
,因为我将其转换为 int,因为您的类型是 int,尽管它们可能应该是 double 或转换更智能地调整你的整数格。
另一种方法是使用运行平均值。它比 Lamperts 慢,并且假设
DataPoint
的支持数据类型是 double。但是,如果点集很大,并且点是随机排序的,则它具有很好的蒙特卡罗收敛性。它还仅枚举一次List
:Well, it would seem that you need to take average of each projection in turn
I cast to int, because your types are
int
, although they probably should bedouble
, or converted to your integer lattice more intelligently.Another way is using running averages. It's slower than Lamperts, and assumes that the backing datatype for the
DataPoint
is double. But if the set of Points is HUGE, and points are ordered randomly it has a nice Monte-Carlo convergence. It also enumarates theList
only once.: