C# group by 消除重复项

发布于 2024-10-21 03:09:59 字数 874 浏览 1 评论 0原文

我正在处理一个大型兴趣点 (POI) 数据集,这些数据集都有纬度/经度值。

我想过滤掉彼此距离很近的 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 方法似乎永远不会被调用?!?

关于最好的方法有什么想法吗?

Im working with a large dataset of point of interest (POI) which all have Lat/Long values.

I want to filter out POIs that are in close proximity to each other. I think that to achieve this I can round the Lat/Long down to X decimal places and group by the results (or call Distinct() or whatever)...

I have written a little LINQ statement which doesnt seem to do what I want,

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

where EqualityComparer is

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();
    }
}

but the Equals method never seems to get called?!?

Any thoughts on the best way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

极致的悲 2024-10-28 03:09:59

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

尝试类似的东西

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

Equals() never gets called because GetHashCode() returns different values for any two objects because you are using GetHashCode() defined in System.Object class .
You'll need to implement GetHashCode() a little differently.

try something like

public int GetHashCode(PointOfInterest obj)
{
    return obj.Longitude.Value.GetHashCode() ^ obj.Latitude.Value.GetHashCode();
}
江南月 2024-10-28 03:09:59

这就是问题所在:

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

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

来自 MSDN 的 IEqualityComparer.GetHashCode()

实现该方法可以提供
定制的哈希码
对象,对应于
定制平等比较
由 Equals 方法提供。

This is the problem:

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

You'll have to override GetHashCode() appropriately as well, probably currently all items are considered different because the hash code doesn't match.

From MSDN for IEqualityComparer.GetHashCode():

Implement this method to provide
customized hash codes for
objects,corresponding to the
customized equality comparison
provided by the Equals method.

妄断弥空 2024-10-28 03:09:59

关于执行此操作的最佳方法有什么想法吗?

简单地:

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;

Any thoughts on the best way to do this?

Simply:

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文