[英]Linq join without equals
我有一个矩形列表和一个点列表。 我想构建一个LINQ查询,它将匹配点列表及其对应的矩形。 像这样的东西:
// Does not compile
var matches = from rect in rectangles
join point in points on rect.Contains(point)
select new { rect, point };
如何使用LINQ实现这样的功能?
编辑:
我的列表大小相同 - 我有一个点与一个矩形匹配,矩形不重叠。
然而,问题的关键不在于解决这个具体问题。 一般来说,我感兴趣的是如何在除了'equals'之外的任何条件下加入两个列表。
您可以使用多个from子句来实现连接
var matches = from p in points
from r in rectangles
where r.Contains(p)
select new { r, p };
多个from子句比join语法更灵活( 参见神话中的5个LINQ神话 )。 你只需要学习这一个,所有的连接都很容易。
您可以使用Enumerable.ToLookup为每个矩形创建一个查找表:
var lookup = points.ToLookup(p => rectangles.First(r => r.Contains(point)));
使用它类似于分组查询:
foreach(var group in lookup)
{
Console.WriteLine("Rectangle {0} contains:", group.Key);
foreach(var point in group)
Console.WriteLine(" {0}", point);
}
在旁注 - 这个查询本质上是二次的,并且可能在非常大的数据集上表现不佳。 如果需要对许多点和/或许多矩形执行此操作,您可能希望研究空间数据结构以便更快地查找。 然而,在这种情况下,这可能不是问题。
您是否尝试过使用where语句,而不是加入它们:
var matches = from rectangle in rectangles
from point in points
where rectangle.Contains(point)
select new { rectangle, point };
有两种方法可以获得你想要的东西。
points.Select(p => new { Point = p, Rectangles = rectangles.Where(r => r.Contains(p) });
这适用于点可能在许多矩形中的情况。
points.Select(p => new { Point = p, Rectangle = rectangles.First(r => r.Contains(p) });
这适用于一个点恰好在一个矩形中的情况。
第二种情况应该在您的方案中最佳。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.