【问题标题】:C# Removing Dublettes from ListC# 从列表中删除 Dublettes
【发布时间】:2014-08-18 13:26:49
【问题描述】:

我有一个几乎每秒都在变化的列表。我想检查列表,如果它变得太大。第一步是从列表中删除重复条目。

有很多方法可以做到这一点。我见过HashTablesLINQ 和其他人。问题是我需要一个快速的方法来完成这个。

列表中可能有很多条目,如果可能的话,用户不应该看到应用程序冻结,因为应用程序正在显示动画。

我不知道是否可以使用HashTables,因为如果可能的话,列表内对象的顺序应该保持不变。

我尝试使用 LINQ 和 GroupBy,但我正在使用 Visual Studio 2008,它不包含该 LINQ 语句。

对象不是很简单。想象一个物体是一辆汽车。它可以有制造商、制造时间、型号名称等。

我只想查看制造商和型号名称是否在列表中的两倍。制造时间并不重要,应该忽略。

最后我想从列表中删除所有重复条目。

我很高兴收到建议。如果您有任何想法,请将它们写下来,我们会看到。

【问题讨论】:

  • 如果您想保留列表内的顺序,还有其他可用的集合类型。我想到了 SortedList 和 SortedDictionary。查看 .NET 集合类型,看看是否符合您的要求。
  • 我必须保持从进入时间开始的顺序。如果列表中有 3 个整数,它可以是这样的:2,3,1。它不是按值排序的。
  • 啊,好的。一种解决方案可能是同时使用列表和字典。首先不要将重复的项目放在列表中,而不是事后查找它们。或者您还需要一个字典来跟踪他们的索引。
  • 这是个好主意。也许我可以在添加之前验证条目。如果它是重复的条目,我可以忽略它。我不知道为什么我没有想到这一点。
  • 一个(未排序的)列表不仅在查找项目时很慢,而且从中删除项目也很慢。因此字典 ;)

标签: c# winforms visual-studio-2008 .net-3.5


【解决方案1】:

一种解决方案是同时使用列表和字典。一开始不将重复项放在 List 中,比事后查找更容易。

使用您的汽车示例:要检查 2 辆汽车在其属性子集上是否相等,您需要一个 EqualityComparer:

class CarComparer : IEqualityComparer<Car>
{
    public bool Equals(Car car1, Car car2) {
        return car1.Manufacturer.Equals(car2.Manufacturer)
            && car1.ModelName.Equals(car2.ModelName);
    }

    public int GetHashCode(Car car) {
        return car.Manufacturer.GetHashCode() * 31 + car.ModelName.GetHashCode();
    }
}

然后您可以使用它来创建一个 HashSet:(与字典相同,只是它只保存键而不是键/值对)

HashSet<Car> uniqueCars = new HashSet<Car>(new CarComparer());

然后,您可以在添加之前使用该 HashSet 来检查 Car 是否存在。

List<Car> carList = new List<Car>();
...
if (!uniqueCars.Contains(car)) {
    uniqueCars.Add(car);
    carList.Add(car);
}

【讨论】:

    【解决方案2】:

    【讨论】:

      【解决方案3】:

      与其在列表太大时删除重复条目,不如一开始就不允许重复条目?一种方法是将您的集合与某种索引结合起来。

      我使用的正常做法是有 2 个集合 - 一个用于数据,一个用于索引。

      List<MyClass> _collection;
      Dictionary<MyClassKey, MyClass> _index;
      

      然后当我添加时,首先我检查索引,如果它不存在则添加 - 否则不要添加。

      void Add(MyClass item)
      {
          if (!_index.ContainsKey[item.Key])
          {
              _collection.Add(item);
              _index.Add(item.Key, item);
          }
      }
      

      这将消除以后删除重复项的问题,因此不会降低 UI 速度。

      显然上面的代码不是线程安全的——它只是为了说明这一点。

      【讨论】:

      • 我认为这是不可能的。我必须显示这个动画的数据,它来自这个列表。但数据输入可能会有所不同。有时每秒可能有数百个对象进入,有时只有几个。如果每秒有太多,动画将只显示它们中的每一个。删除 dublettes 使动画只显示每个对象一次。如果删除重复项还不够,还有更多步骤可以提高性能。
      猜你喜欢
      • 1970-01-01
      • 2011-09-20
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-14
      • 1970-01-01
      相关资源
      最近更新 更多