是否可以使用LINQ转换包含坐标元组(x,y)的平面双精度数组,即。 [x0,y0,...,xN,yN]到一个半长的数组,包含Point
类中包含的相同坐标,即[p0,...,pN]?
最好是.NET 3.5,但也对4.0感兴趣。
答案 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();