Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ to transform array [x0,y0, ..., xN, yN] into enumerable [p0, ..., pN]

Tags:

c#

.net

linq

Is it possible to use LINQ to transform a flat array of doubles containing coordinate tuples (x, y),i.e. [x0,y0, ..., xN, yN] to an array of half the length containing the same coordinates wrapped in a Point-class, i.e. [p0, ..., pN]?

Preferably .NET 3.5, but also interrested in 4.0.

like image 357
larsmoa Avatar asked Jul 06 '11 06:07

larsmoa


2 Answers

You can use .Batch from Jon Skeet's morelinq:

IEnumerable<Point> points = coordinates.Batch(2,pair => new Point(pair.ElementAt(0), pair.ElementAt(1)));

In all honestly, the simplest solution is probably using a method (here with ints):

public IEnumerable<Point> GetPoints(int[] coordinates)
{
    for (int i = 0; i < coordinates.Length; i += 2)
    {
        yield return new Point(coordinates[i], coordinates[i + 1]);
    }
}
like image 159
Kobi Avatar answered Sep 26 '22 03:09

Kobi


double[] arr = { 1d, 2d, 3d, 4d, 5d, 6d };
var result = arr.Zip(arr.Skip(1), (x, y) => new Point(x, y))
                .Where((p, index) => index % 2 == 0);

EDIT: In this LINQ statement, the collection is looped through twice, which is not efficient. A better solution is using a for loop. And Zip is new in C# 4.0, an alternative is:

var result = arr.Select((n, index) => new Point(n, arr[index + 1]))
                .Where((p, index) => index % 2 == 0);
like image 20
Cheng Chen Avatar answered Sep 27 '22 03:09

Cheng Chen