Find the distance required to navigate a list of points using linq
Using linq given a IEnumerable of two dimensional points, Find the distance required to navigate all points assuming the points are visited in the order they appear in the list.
I thought I might be able to somehow use the .Aggregate<> function but can't figure out how to make it work. The problem is the aggregate returns the same type as the list, which开发者_开发技巧 is a point I need a scalar (double).
If this problem is not solvable using linq, it would be interesting to know what class of problem can and what class of problem can not be solved using linq.
This is not homework but is a required step in a personal project to help me learn linq.
This is much easier if you use (or replicate) the Zip extension method available in .net 4:
var distances = points.Zip(points.Skip(1), Distance);
double totalDistance = distances.Sum();
using the Distance method:
double Distance(Point p1, Point p2)
{
double dx = p1.X-p2.X;
double dy = p1.Y-p2.Y;
return Math.Sqrt( dx*dx+dy*dy );
}
Bart explains (and shows you how to implement) zip on his blog:
static class Enumerable
{
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> func)
{
var ie1 = first.GetEnumerator();
var ie2 = second.GetEnumerator();
while (ie1.MoveNext() && ie2.MoveNext())
yield return func(ie1.Current, ie2.Current);
}
}
How about this? Assuming:
struct Point
{
public int X;
public int Y;
public Point(int x, int y) { X=x; Y=y; }
}
double Distance(Point p1, Point p2)
{
return Math.Sqrt( Math.Pow(p1.X-p2.X,2) + Math.Pow(p1.Y-p2.Y,2) );
}
var list = new List<Point>{...};
Then
var distance = list
.Select( (p,i) => i == list.Count-1? 0 : Distance(p,list[i+1]) ).Sum();
精彩评论