# Use linq to compute length of line defined as array of points

I have an array of points:

`````` Point[] line; // { Point(1,1), Point(2,3), Point(1,1) }
``````

Assuming Point has the relevant operators, what's the most linq-y way of computing the length of this line?

My best effort so far is:

``````float length = Enumerable.Range(0, line.Length-2)
.Select(pointIndex => (line[pointIndex+1] - line[pointIndex]).Magnitude)
.Sum();
``````

Seems like there's a lot of subscripting in there though.

I would think there's a way to do something like this pseudocode:

``````float length = line.PairwiseMap(p1, p2 => (p2 - p1).Magnitude).Sum();
``````

?

-

Another possible answer (first time I've ever suggested two answers) is to keep your existing approach, but modified just a little bit by using `.Select()`'s under-appreciated little brother that gives you access to an index variable:

``````float length = line.Skip(1)
.Select((point, index) => (point - line[index]).Magnitude)
.Sum();
``````

Heck, speaking of overloads. You can also keep your existing approach but use `.Sum()`'s overload:

``````Enumerable.Range(0, line.Length - 1)
.Sum(pointIndex => (line[pointIndex + 1] - line[pointIndex]).Magnitude)
``````
-

You could use linq `Zip` instead of `PairwiseMap`. There is a drawback, you have to create two new enumerations with points:

``````//  collection of point/tuples
var points = new[] {
Tuple.Create(1f, 1f),
Tuple.Create(2f, 3f),
Tuple.Create(5f, 5f),
Tuple.Create(0f, 0f)
};

Enumerable
.Range(0, points.Length - 1)
.Select(index => Math.Sqrt(Math.Pow(points[index].Item1 - points[index + 1].Item1, 2) + Math.Pow(points[index].Item2 - points[index + 1].Item2, 2)))
.Sum();

var left = points.Take(points.Length - 1); // starting points of verctors
var right = points.Skip(1); // ending points of verctors

// zip and calculate magnitude
left
.Zip(right, (x, y) =>
Math.Sqrt(Math.Pow(x.Item1 - y.Item1, 2f) + Math.Pow(x.Item2 - y.Item2, 2f)))
.Sum()
``````
-

Use `.Aggregate()` which is a way to fold an operation over a list with an accumulator

``````if (line.Any())
length = line.Skip(1)
.Aggregate(
new { Point = line.First(), Length = 0d }, //seed
(accum, point) => new { Point = point, Length = accum.Length + (point - accum.Point).Magnitude })
.Length
else
length = 0;
``````

In this case, our accumulator is a `Tuple<Point, double>`, where the `double` is the length so far.

One advantage to this approach is that your points collection doesn't need to be an array or even have random access, just be an `IEnumerable<Point>`. OTOH, `.Aggregate()` can be clunky, and you may prefer the readability of @akim's answer.

-
You're right, it's almost too slick. Very nice though! –  tenpn Jul 24 '12 at 8:36