簡體   English   中英

如何從嵌套對象列表中刪除重復項?

[英]How to remove duplicates from a list of nested objects?

我知道有很多答案建議覆蓋 equals 和 hashcode,但就我而言,這是不可能的,因為所使用的對象是從 DLL 導入的。

首先,我有一個名為DeploymentData的對象列表。

這些對象以及其他屬性包含以下兩個: Location(double x, double y, double z)Duct(int id)

目標是刪除那些具有相同Location參數的。

首先,我將它們按Duct分組,因為Location如果在另一個管道上則不能相同。

var groupingByDuct = deploymentDataList.GroupBy(x => x.Duct.Id).ToList();

然后是實際算法:

List<DeploymentData> uniqueDeploymentData = new List<DeploymentData>();
foreach (var group in groupingByDuct) {
   uniqueDeploymentData 
      .AddRange(group 
      .Select(x => x)
      .GroupBy(d => new { d.Location.X, d.Location.Y, d.Location.Z })
      .Select(x => x.First()).ToList());
}

這確實有效,但為了正確檢查它們是否確實重復,應該比較整個位置。 為此,我做了以下方法:

private bool CompareXYZ(XYZ point1, XYZ point2, double tolerance = 10)
{
   if (System.Math.Abs(point1.X - point2.X) < tolerance &&
       System.Math.Abs(point1.Y - point2.Y) < tolerance &&
       System.Math.Abs(point1.Z - point2.Z) < tolerance) {
      return true;
   }
   return false;
}

但是我不知道如何將其應用於上面編寫的代碼。 總結:

  • 如果沒有所有這些方法調用,我如何編寫上面的算法?
  • 如何調整上述算法以使用CompareXYZ方法以獲得更好的精度?
  • 效率?

過濾重復項的一種簡單方法是使用帶有自定義相等比較器的哈希集。 這是實現IEqualityComparer的class,例如:

public class DeploymentDataEqualityComparer : IEqualityComparer<DeploymentData>
{
  private readonly double _tolerance;

  public DeploymentDataEqualityComparer(double tolerance)
  {
    _tolerance = tolerance;
  }

  public bool Equals(DeploymentData a, DeploymentData b)
  {
    if (a.Duct.id != b.Duct.id)
      return false; // Different Duct, therefore not equal
    if (System.Math.Abs(a.Location.X - b.Location.X) < _tolerance &&
       System.Math.Abs(a.Location.Y - b.Location.Y) < _tolerance &&
       System.Math.Abs(a.Location.Z - b.Location.Z) < _tolerance) {
      return true;
     }
     return false;
  }

  public GetHashCode(DeploymentData dd)
  {
    // If the classes of the library do not implement GetHashCode, you can create a custom implementation
    return dd.Duct.GetHashCode() | dd.Location.GetHashCode();
  }
}

為了過濾重復項,您可以將它們添加到 HashSet:

var hashSet = new HashSet<DeploymentData>(new DeploymentDataEqualityComparer(10));
foreach (var deploymentData in deploymentDataList)
  hashSet.Add(deploymentData);

這樣,您就不需要按管道分組並使用 HashSet 的增強性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM