Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the distance required to navigate a list of points using linq

Tags:

c#

.net

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.

like image 846
trampster Avatar asked Dec 01 '25 21:12

trampster


2 Answers

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); 
    } 
}
like image 149
Rob Fonseca-Ensor Avatar answered Dec 04 '25 10:12

Rob Fonseca-Ensor


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();
like image 40
Winston Smith Avatar answered Dec 04 '25 10:12

Winston Smith



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!