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