C#group by消除重复

时间:2011-03-07 01:21:51

标签: c# linq group-by

我正在处理一个大的兴趣点数据集(POI),它们都有Lat / Long值。

我想过滤掉彼此非常接近的POI。我认为要实现这一点,我可以将Lat / Long向下舍入到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方法似乎永远不会被调用?!?

有关最佳方法的任何想法吗?

3 个答案:

答案 0 :(得分:5)

Equals()永远不会被调用,因为GetHashCode()会为任何两个对象返回不同的值,因为您使用GetHashCode()类中定义的System.Object。 你需要以不同的方式实现GetHashCode()。

尝试类似

的内容
public int GetHashCode(PointOfInterest obj)
{
    return obj.Longitude.Value.GetHashCode() ^ obj.Latitude.Value.GetHashCode();
}

答案 1 :(得分:3)

这是问题所在:

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

您还必须适当地覆盖GetHashCode(),可能目前所有项目都被视为不同,因为哈希码不匹配。

来自MSDN的IEqualityComparer.GetHashCode()

  

实施此方法以提供   自定义哈希码   对象,对应于   定制的平等比较   由Equals方法提供。

答案 2 :(得分: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;