[英]Select more than one property using Linq
Let's say we have a Line
class defined by Point startPoint
and Point endPoint
. 假设我们有一个由
Point startPoint
和Point endPoint
定义的Line
类。
If I have list of these lines, how can I extract all the points in them into one List<Point>
using LINQ . 如果我有这些行的列表,如何使用LINQ将它们中的所有点提取到一个
List<Point>
中。
This is what I have so far: 这是我到目前为止的内容:
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();
If you want a shorter way, you can do something like this: 如果您想使用更短的方法,可以执行以下操作:
var points = lines.SelectMany(l => new[] { l.StartPoint, l.EndPoint }).ToList();
However, your current code is debateably more readable, but more importantly, does not create an array for each line
you iterate. 但是,您当前的代码具有更好的可读性,但更重要的是,它不会为您迭代的每一
line
创建一个数组。
However, you don't need to invoke ToList()
for each set, you can simply write: 但是,您不需要为每个集合调用
ToList()
,只需编写即可:
var points = lines.Select(l => l.StartPoint).Concat(lines.Select(l => l.EndPoint)).ToList();
You can do this in a few different ways. 您可以通过几种不同的方式来执行此操作。 One is to use
Tuple<Point, Point>
: 一种是使用
Tuple<Point, Point>
:
IEnumerable<Tuple<Point, Point>> r = lines.Select(l => new Tuple<Point, Point>(l.StartPoint, l.EndPoint));
To access these then you have to keep in mind that StartPoint
would be Item1
and EndPoint
will be Item2
: 要访问这些文件,您必须记住
StartPoint
将是Item1
, EndPoint
将是Item2
:
foreach ( Tuple<Point, Point> se in r )
{
var start = se.Item1;
var end = se.Item2;
}
Another one could be to make an array of 2 elements each : 另一个可能是使每个元素包含两个元素:
IEnumerable<Point[]> r = lines.Select(l => new Point[2]{ l.StartPoint, l.EndPoint });
To access these you have to keep in mind that index 0
contains your StartPoint
and index 1
contains your EndPoint
: 要访问它们,必须记住索引
0
包含您的StartPoint
,索引1
包含您的EndPoint
:
foreach( Point[] parr in r )
{
if( parr.Length == 2 )
{
var start = parr[0];
var end = parr[1];
}
}
You can always create a flat model containing only these two properties and then just cast/create it in the Select
. 您始终可以创建仅包含这两个属性的平面模型,然后在
Select
铸造/创建。
There are dozens of ways to achieve what you want. 有很多方法可以实现您想要的。 The real question is what do you want to do with this result later.
真正的问题是您以后要如何处理此结果。
Your solution is the closer you can get to it. 您的解决方案离您越近。 If you don't want to enumerate twice the list you should go for a Foreach/Map approach:
如果您不想对列表进行两次枚举,则应采用Foreach / Map方法:
var points = new List<Point>();
lines.Map(line =>
{
points.Add(line.startPoint);
points.Add(line.EndPoint);
} );
If you don't want to use Concat you can use Union: 如果您不想使用Concat,则可以使用Union:
lines.Select(o => o.StartPoint).Union(lines.Select(o => o.EndPoint)).ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.