LINQ转换数组[x0,y0,…], xN, yN] into enumerable [p0,…], pN]
本文关键字:into enumerable p0 pN yN xN 数组 y0 LINQ 转换 x0 | 更新日期: 2023-09-27 18:01:23
是否可以使用LINQ来转换包含坐标元组(x, y)的双精度对象的平面数组?(x0, y0,…, xN, yN]转换为包含相同坐标的一半长度的数组,用Point
-类封装,即[p0,…], pN) ?
最好是。net 3.5,但也对4.0感兴趣。
你可以从Jon Skeet的morelinq:
使用.Batch
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]);
}
}
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
在c# 4.0中是新的,另一种选择是:
var result = arr.Select((n, index) => new Point(n, arr[index + 1]))
.Where((p, index) => index % 2 == 0);
这将只循环一次,并将在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;
}
}
当然。我没有编译/运行,所以它可能有拼写错误,但要点应该是正确的。
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();