繁体   English   中英

Linq加入没有平等

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM