You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

合并无重复嵌套线路列表:LatLng数组去重实现问题咨询

解决嵌套线路列表合并去重的问题

我来帮你搞定这个线路网络合并并排除完全重复线路的需求~

首先得搞清楚为啥你之前用Distinct或者Contains没效果:

  • LatLng类默认没实现值相等的比较逻辑,即使两个实例的经纬度完全一样,默认的引用比较也会把它们当成不同对象
  • 数组是引用类型,Contains默认比较的是数组的引用地址,而不是数组里的元素内容

要解决这个问题,我们需要分两步处理:先让LatLng能正确比较值相等,再让线路数组能基于元素内容判断是否重复。

步骤1:给LatLng实现值相等比较

因为经纬度是double类型,直接用Equals比较可能会有浮点精度误差,所以我们可以写一个自定义的坐标比较器,或者让LatLng实现IEquatable<LatLng>接口。这里推荐用单独的比较器,不用修改原类:

public class LatLngValueComparer : IEqualityComparer<LatLng>
{
    // 自定义容差,根据业务需求调整,1e-9对应约0.1毫米的精度
    private const double Tolerance = 1e-9;

    public bool Equals(LatLng x, LatLng y)
    {
        if (x == null && y == null) return true;
        if (x == null || y == null) return false;
        return Math.Abs(x.Latitude - y.Latitude) < Tolerance 
            && Math.Abs(x.Longitude - y.Longitude) < Tolerance;
    }

    public int GetHashCode(LatLng obj)
    {
        if (obj == null) return 0;
        // 组合经纬度的哈希码,确保相等的实例哈希码一致
        return HashCode.Combine(obj.Latitude.GetHashCode(), obj.Longitude.GetHashCode());
    }
}

步骤2:合并线路并去重

有了坐标的相等比较逻辑后,我们就可以判断两条线路是否完全重复了。这里提供两种实用的实现方式:

方式1:遍历新线路,判断后添加

把原线路转成List方便操作,然后逐个检查新线路是否已存在,不存在就添加:

// 假设你的lineNetwork和newLineNetwork都是IEnumerable<LatLng[]>
var lineList = lineNetwork.ToList();
var latLngComparer = new LatLngValueComparer();

foreach (var newLine in newLineNetwork)
{
    // 检查现有线路中是否有完全匹配的线路
    bool isDuplicate = lineList.Any(existingLine => 
        existingLine.SequenceEqual(newLine, latLngComparer));
    
    if (!isDuplicate)
    {
        lineList.Add(newLine);
    }
}

// 转回IEnumerable<LatLng[]>
lineNetwork = lineList;

方式2:用Distinct+线路比较器去重

写一个专门比较线路数组的比较器,然后用Concat合并后调用Distinct一次性去重:

public class LineEqualityComparer : IEqualityComparer<LatLng[]>
{
    private readonly IEqualityComparer<LatLng> _latLngComparer;

    public LineEqualityComparer(IEqualityComparer<LatLng> latLngComparer)
    {
        _latLngComparer = latLngComparer ?? new LatLngValueComparer();
    }

    public bool Equals(LatLng[] x, LatLng[] y)
    {
        if (x == null && y == null) return true;
        if (x == null || y == null) return false;
        // 用SequenceEqual比较数组元素,传入自定义的坐标比较器
        return x.SequenceEqual(y, _latLngComparer);
    }

    public int GetHashCode(LatLng[] obj)
    {
        if (obj == null) return 0;
        int hash = 17;
        foreach (var coord in obj)
        {
            hash = hash * 31 + _latLngComparer.GetHashCode(coord);
        }
        return hash;
    }
}

// 合并并去重
lineNetwork = lineNetwork
    .Concat(newLineNetwork)
    .Distinct(new LineEqualityComparer(new LatLngValueComparer()));

这样处理后,你例子中的line2因为和line1的坐标完全一致,就会被正确识别为重复线路而排除,line1和line3则会被保留下来。

内容的提问来源于stack exchange,提问作者cullimorer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:27:56