2015-08-25 91 views
3

我有一個數據庫充滿座標(x,y),我希望找到最接近點的座標。 (可以有多個最接近這一點)LINQ找到最近的座標

我寫這2 LINQ的,但必須有一個SMARTE的方式,不是通過數據庫去兩次:

var closestDistance = _context.Coordinates.Min(x => 
          Math.Sqrt(Math.Pow((point.coordX - x.CoordX), 2) + 
            Math.Pow((point.coordY- x.CoordY), 2))); 
var closest = _context.Coordinates.Where(x=> closestDistance == 
          Math.Sqrt(Math.Pow((point.coordX - x.CoordX), 2) + 
            Math.Pow((point.coordY - x.CoordY), 2))); 

如何優化這個?

+0

順便說一句,如果你只是想找到最接近的(而不是實際的距離),你不需要平方根值。 –

+0

你不能使用kd樹嗎? –

+0

@Matthew我真的不知道... Math.Pow會很容易解決..如果EF翻譯,我的問題仍然會是,我怎麼能達到我想要的結果只有一個全表掃描,而不是2現在 – sirius

回答

3

你可以利用一個羣。此外,您不必計算平方根。你可以使用相應差異的平方和。

使用GroupBy,您可以構建一組組,其中的關鍵是每個組的點與您感興趣的點的距離。然後根據該鍵的值製作一組OrderBy。最後你選擇第一組。這包含你正在尋找的點。

var closest = _context.Coordinates 
         .GroupBy(x => Math.Pow((point.coordX - x.CoordX), 2) + Math.Pow((point.WinningCoordY - x.CoordY), 2)) 
         .OrderBy(x=>x.Key) 
         .First(); 
5
  1. 不能calc下Math.Sqrt - 沒關係(3> 2和3 * 3> 2 * 2)
  2. 您可以通過DIST排序,先取:

var closest = _context.Coordinates.OrderBy(x => 
       Math.Pow((point.coordX - x.CoordX), 2) + Math.Pow((point.WinningCoordY - x.CoordY), 2)) 
      .First(); 
  • 此外,利用乘法替換Math.Pow - 這將是快得多:

  • var closest = _context.Coordinates.OrderBy(x => 
           (point.coordX - x.CoordX) * (point.coordX - x.CoordX) + (point.WinningCoordY - x.CoordY) * (point.WinningCoordY - x.CoordY)) 
          .First(); 
    
    +0

    您有一些相當不錯的觀點。謝謝您的幫助。我需要的不僅僅是第一個,但是如果我按照Christos的建議做出一個組,我想我得到了我需要的東西 – sirius

    +0

    @sirius我不注意地閱讀你的問題,錯過了關於多點的要求,所以,我可以通過分組來提高我的答案。但我建議你替換Math.Pow – Backs

    相關問題