2017-02-24 71 views
1

多个属性比方说,我们必须通过Point startPointPoint endPoint定义的Line类。选择使用LINQ

如果我有这些行的列表,如何使用LINQ将它们中的所有点提取到一个List<Point>中。

这是我到目前为止有:

IList<Point> points1 = lines.Select(o => o.StartPoint).ToList(); 
IList<Point> points2 = lines.Select(o => o.EndPoint).ToList(); 

IList<Point> points = points1.Concat(points2).ToList(); 
+1

什么你的解决方案有问题吗? –

+0

我想知道是否有一个线路清洁解决方案。 – Vahid

+0

不能使用'Concat'如果'StartPoint'&'EndPoint'是不同的类型。 –

回答

4

如果你想有一个较短的方式,你可以做这样的事情:

​​

然而,当前的代码是debateably更具可读性,但更重要的是,不会为你遍历每个line的数组。

不过,你不需要调用ToList()每一组,可以简单的写:

var points = lines.Select(l => l.StartPoint).Concat(lines.Select(l => l.EndPoint)).ToList(); 
1

您可以在几个不同的方式做到这一点。一种是使用Tuple<Point, Point>

IEnumerable<Tuple<Point, Point>> r = lines.Select(l => new Tuple<Point, Point>(l.StartPoint, l.EndPoint)); 

要访问这些,那么你必须记住,StartPointItem1EndPointItem2

foreach (Tuple<Point, Point> se in r) 
{ 
    var start = se.Item1; 
    var end = se.Item2; 
} 

另外一个可能是使数组每个2个元素:

IEnumerable<Point[]> r = lines.Select(l => new Point[2]{ l.StartPoint, l.EndPoint }); 

要访问这些,您必须记住索引0包含您StartPoint和索引1包含您EndPoint

foreach(Point[] parr in r) 
{ 
    if(parr.Length == 2) 
    { 
     var start = parr[0]; 
     var end = parr[1]; 
    } 
} 

你总是可以创建只包含这两种性质的平面模型,然后就投/在Select创建它。

有几十个的方式来实现你想要什么。真正的问题是你以后想要用这个结果做什么。

1

你的解决方案是,你可以得到它的更近。如果你不想枚举两次你应该去一个Foreach/MAP方法列表:

var points = new List<Point>(); 

lines.Map(line => 
{ 
    points.Add(line.startPoint); 
    points.Add(line.EndPoint); 
}); 

如果你不想使用的毗连就可以使用联盟:

lines.Select(o => o.StartPoint).Union(lines.Select(o => o.EndPoint)).ToList();