LINQ将数组[x0,y0,...,xN,yN]转换为可枚举的[p0,...,pN]

时间:2011-07-06 06:55:03

标签: c# .net linq

是否可以使用LINQ转换包含坐标元组(x,y)的平面双精度数组,即。 [x0,y0,...,xN,yN]到一个半长的数组,包含Point类中包含的相同坐标,即[p0,...,pN]?

最好是.NET 3.5,但也对4.0感兴趣。

4 个答案:

答案 0 :(得分:6)

您可以使用Jon Skeet的.Batch中的morelinq

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

老实说,最简单的解决方案可能是使用方法(这里有int s):

public IEnumerable<Point> GetPoints(int[] coordinates)
{
    for (int i = 0; i < coordinates.Length; i += 2)
    {
        yield return new Point(coordinates[i], coordinates[i + 1]);
    }
}

答案 1 :(得分:3)

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);

编辑:在这个LINQ语句中,集合循环两次,效率不高。更好的解决方案是使用for循环。 Zip是C#4.0中的新功能,另一种选择是:

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

答案 2 :(得分:2)

这将循环一次,将在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;
    }

}

答案 3 :(得分:0)

不确定。我没有编译/运行,所以它可能有拼写错误,但要点应该是正确的。

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();