使用linq

时间:2016-10-04 19:14:26

标签: c# linq

我有以下坐标数组:

double[] points = { 1, 2, 3, 4, 5, 6 };

然后我有以下课程:

public class clsPoint
{
    public double X { get; set; }
    public double Y { get; set; }
}

我需要将这些点复制到List对象中。数组中的第一个点是X,数组中的第二个点是Y.这是我到目前为止但它不正确:

List<clsPoint> lstPoints = points
                           .Select(coord => new clsPoint
                           {
                               X = coord[0],
                               Y = coord[1]
                           }).ToList();

预期结果

clsPoint Objects List (lstPoints)
X = 1 , Y = 2
X = 3 , Y = 4
X = 5 , Y = 6

任何帮助将不胜感激。感谢。

3 个答案:

答案 0 :(得分:2)

使用接收当前索引的Select重载,您可以设置分组规则(在这种情况下,每两个数字使用不同的ID),然后按其分组,最终创建新的clsPoint

double[] points = { 1, 2, 3, 4, 5, 6 };

var result = points.Select((item, index) => new { item, index = index / 2 })
                   .GroupBy(item => item.index, item => item.item)
                   .Select(group => new clsPoint { X = group.First(), Y = group.Last() })
                   .ToList();

使用简单的for循环执行此操作将如下所示:

List<clsPoint> result = new List<clsPoint>();
for (int i = 0; i < points.Length; i += 2)
{
    result.Add(new clsPoint { X = points[i], Y = points.ElementAtOrDefault(i+1) });
}

答案 1 :(得分:2)

您可以生成一系列连续值,直到数组的一半,然后您可以使用这些值作为索引进行投影以获取对。

var result=Enumerable.Range(0, points.Length / 2).Select(i=>new clsPoint{X=points[2*i],Y=points[2*i+1]});

更新

这是使用Zip扩展方法和Where扩展方法的一次重载来获取索引的另一种解决方案:

var r2 = points.Where((e, i) => i % 2 == 0)
               .Zip(points.Where((e, i) => i % 2 != 0), (a, b) => new clsPoint{X= a, Y= b });

答案 2 :(得分:2)

我认为在将它们送入课堂之前,您可能有更好的方法来撰写积分。在这种情况下,简单的for循环也可能更好。

但是,在LINQ中,您首先要使用投影来收集索引,以便您可以根据对进行分组,然后使用分组中的第二个投影来填充该类。

看起来像这样

points.Select((v,i) => new { 
    val = v, 
    i = i 
}).GroupBy(o => o.i%2 != 0 ? o.i-1 : o.i).Select(g => new clsPoint() {
    X = g.First().val,
    Y = g.Last().val
});