2011-03-07 56 views
0

我正在處理一個大型的興趣點(POI)數據集,它們都有Lat/Long值。C#group by以消除重複項

我想篩選出彼此靠近的POI。我認爲爲了達到這個目的,我可以將緯度/經度向下舍入到X小數位,並按結果進行分組(或者撥打Distinct()或其他)...

我寫了一點LINQ語句,它似乎沒有做什麼我想,

var l1 = (from p in PointsOfInterest where p.IsVisibleOnMap select p).Distinct(new EqualityComparer()).ToList(); 

其中EqualityComparer

public class EqualityComparer : IEqualityComparer<PointOfInterest> 
{ 
    public bool Equals(PointOfInterest x, PointOfInterest y) 
    { 
     return Math.Round(x.Latitude.Value, 4) == Math.Round(y.Latitude.Value, 4) && 
      Math.Round(x.Longitude.Value, 4) == Math.Round(y.Latitude.Value, 4); 
    } 

    public int GetHashCode(PointOfInterest obj) 
    { 
     return obj.GetHashCode(); 
    } 
} 

但Equals方法似乎從來就沒叫什麼?!?

有關最佳方式的任何想法?

回答

5

Equals()不會被調用,因爲對於任何兩個物體GetHashCode()返回不同的值,因爲您使用的是System.Object類中定義GetHashCode()。 你需要實現GetHashCode()稍有不同。

嘗試像

public int GetHashCode(PointOfInterest obj) 
{ 
    return obj.Longitude.Value.GetHashCode()^obj.Latitude.Value.GetHashCode(); 
} 
+1

嗯,所以這種相等比較,也許返回0作爲哈希碼會做的伎倆 – driushkin 2011-03-07 01:40:42

+0

賓果:)感謝您的幫助 – Mark 2011-03-07 08:32:28

3

這就是問題所在:

public int GetHashCode(PointOfInterest obj) 
{ 
    return obj.GetHashCode(); 
} 

你必須適當地覆蓋GetHashCode()爲好,大概目前所有項目都被認爲是不同的,因爲哈希代碼沒有按」 t匹配。

從MSDN爲IEqualityComparer.GetHashCode()

實現此方法可用於 對象提供 定製散列碼,對應於由Equals方法提供的定製 相等比較 。

1

有關最佳方式的任何想法?

簡單:

IEnumerable<PointOfInterest> result = 
    from p in PointsOfInterest 
    where p.IsVisibleOnMap 
    group p by new 
    { 
    Latitude = Math.Round(p.Latitude.Value, 4), 
    Longitude = Math.Round(p.Longitude.Value, 4) 
    } into g 
    let winner = g.First() 
    select winner;