LINQ to convert an array [x0, y0, ..., xN, yN] to enumerated [p0, ..., pN]

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

Preferably .NET 3.5, but also interrested in 4.0.

+5
source share
4 answers

You can use .Batchfrom Jon Skeet morelinq :

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

In fact, the simplest solution probably uses 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]);
    }
}
+6
source
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: LINQ , . for. Zip # 4.0, :

var result = arr.Select((n, index) => new Point(n, arr[index + 1]))
                .Where((p, index) => index % 2 == 0);
+3

3.5

        int[] arr = new int[] { 1, 1, 2, 2, 3, 3 };

        if (arr.Length % 2 != 0)
            throw new ArgumentOutOfRangeException();

        Point[] result = arr
                        .Where((p, index) => index % 2 == 0)
                            .Select((n, index) => new Point(n, arr[index * 2 + 1]))
                               .ToArray();

(, "" ) :

public static class Program
{

    public static IEnumerable<Point> ToPoints(this IEnumerable<int> flat)
    {
        int idx = 0;
        while(true)
        {
            int[] parts = flat.Skip(idx).Take(2).ToArray();
            if (parts.Length != 2)
                yield break;

            idx += 2;
            yield return new Point(parts[0], parts[1]);
        }
    }

    static void Main(string[] args)
    {
        int[] arr = new int[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 };

        var x = arr.ToPoints().ToArray();

        return;
    }

}

+2
source

Of course. I did not compile / run, so it may have typos, but the gist should be correct.

var newArray = source.Aggregate(new List<double>, 
     (xCoords, next) => 
        {
           if(xCoords.length % 2 == 0) {
              xCoords.Add(next);
           }

           return xCoords;
        },
     xCoords => xCoords
     ).Zip(source.Aggregate(new List<double>, 
        (yCoords, next) => 
           {
              if(yCoords.length % 2 != 0) {
                 yCoords.Add(next);
              }

              return yCoords;
           },
        yCoords => yCoords
    , (x, y) => new Point(x, y)
    ).ToArray();
0
source

All Articles