Reputation: 83254
I have a class:
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
}
Given a list<PointD>
, how to get the average of it using LINQ? A for
loop equivalent will be something like this:
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};
You can use any built-in LINQ function only. You can't define an extension that takes care of this function.
Any idea?
Edit: Of course, you can use two separate Sum
extension method to Sum for X and Y component before merging them. But this is not what I want. What I want is a single query/ method that does the job
Upvotes: 8
Views: 23704
Reputation: 136637
You'll need to use the Aggregate
method instead so you can provide your own aggregation function (Sum
is just a convenient specialized case of this method). Something like:
points.Aggregate(new PointD(0, 0), (a, p) => a + p);
I know you say you don't want any additional methods defined, but if this is a common operation I'd be inclined to write an extension method for this, i.e.
public static PointD Sum(this IEnumerable<PointD> source)
{
return source.Aggregate(new PointD(0, 0), (a, p) => a + p);
}
Because it's much more readable to be able to write:
points.Sum();
Upvotes: 6
Reputation: 61795
[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);
}
Upvotes: 0
Reputation: 147340
The Aggregate
function would come in handy here.
var sum = list.Aggregate((acc, cur) => acc + cur);
var average = list.Aggregate((acc, cur) => acc + cur) / list.Count;
Just insure that you have the /
operator defined for types PointD
and int
, and this should do the job.
Note: I'm not quite sure whether you want the sum or average here (your question is somewhat ambiguous about this), but I've included examples for both.
Upvotes: 13