我正在尝试合并两个嵌套列表。我有一个LatLng类,它包含两个属性,纬度和经度 - 两者都是双打。这个类是从名为DotNetCoords的NuGet包中引入的。一条线表示为LatLngs数组,我在网络中有一个数字行,如下所示:
IEnumerable<LatLng[]> lineNetwork;
我想要添加另一个网络线,但是我要尝试区分重复,但我不认为LatLng是等同的,所以这似乎不起作用。
我也尝试过以下无法解决的问题。
IEnumerable<LatLng[]> lineNetwork;
IEnumerable<LatLng[]> newLineNetwork;
lineNetwork.AddRange(newLineNetwork.Where(x => !lineNetwork.Contains(x)));
在添加之前,需要检查行中的所有坐标是否相等。例如:
LatLng[] line1 = {
new LatLng(Latitude: 0.1, Longitude: 0.1),
new LatLng(Latitude: 0.2, Longitude: 0.2),
new LatLng(Latitude: 0.3, Longitude: 0.3)
}
LatLng[] line2 = {
new LatLng(Latitude: 0.1, Longitude: 0.1),
new LatLng(Latitude: 0.2, Longitude: 0.2),
new LatLng(Latitude: 0.3, Longitude: 0.3)
}
LatLng[] line3 = {
new LatLng(Latitude: 0.1, Longitude: 0.1),
new LatLng(Latitude: 0.4, Longitude: 0.4),
new LatLng(Latitude: 0.5, Longitude: 0.5)
}
Line1&amp;将添加Line3,但不会添加Line2,因为所有坐标都与Line1共享。
答案 0 :(得分:2)
一种方法是实施IEqualityComparer
,以便比较LatLng
的两个实例,而不是使用IEnumerabe<T>.Distinct
。但是,由于您拥有该类型的数组,您还需要比较器来处理该数组类型:
class MyComparer : IEqualityComparer<LatLng[]>
{
public bool Equals(LatLng[] x, LatLng[y])
{
return a.SequenceEquals(y, new MyLatLngComparer(0.001));
}
public int GetHashCode(LatLng[] x)
{
return x.First().GetHashCode();
}
}
由于LatLng
- 类没有自己的相等实现,因此您必须在SequenceEquals
内提供自己的实现:
class MyLatLngComparer : IEqualityComparer<LatLng>
{
private readonly double Tolerance;
public MyLatLngComparer(double tolerance) { this.Tolerance = tolerance ;}
public bool Equals(LatLng x, LatLng y)
{
return Math.Abs(x - y) <= Tolerance;
}
public int GetHashCode(LatLng x)
{
return x.GetHashCode();
}
}
在这里,您将看到如何比较浮点值。如上所示,这些类型的平等应该通过一些小容忍来实现,以避免舍入问题。
最后,您可以将Distinct
与提供的比较器一起使用:
lineNetwork.AddRange(newLineNetwork.Distinct(new MyComparer()));
为简洁起见,我也省略了一些空检查。你应该特别检查你的阵列是否有一个元素,例如在MyComparer.GetHashCode
内。
答案 1 :(得分:-1)
三种可能的选择:
LatLng
并覆盖Equals和GetHashCode IEquatable<LatLng>
(类似于上一个选项,但效率更高)Contains
操作(您的代码失败,因为Contains
尝试根据对象引用搜索相等性。唯一的方法是覆盖Equals方法)