c#从列表中删除Dublettes
本文关键字:删除 Dublettes 列表 | 更新日期: 2023-09-27 18:10:37
我有一个几乎每秒都在变化的列表。如果名单太长,我想检查一下。第一步将从列表中删除双表项。
有很多方法可以做到这一点。我见过HashTables
, LINQ
和其他。问题是我需要一个快速的方法来完成这个。
列表中可能有相当多的条目,如果可能的话,用户不应该看到应用程序冻结,因为应用程序正在显示动画。
我不知道,我是否可以使用HashTables
,因为列表中对象的顺序应该保持不变,如果可能的话。
我尝试使用LINQ和GroupBy,但我正在Visual Studio 2008中工作,其中不包含LINQ语句。
对象不是很简单。想象一个物体是一辆汽车。可包含:生产厂家、生产时间、型号等。
我只想看到制造商和模型名称是否在列表中出现两次。生产时间不重要,可以忽略。
最后我想从列表中删除所有的双元素。
我很乐意听取建议。如果你有什么想法,请写下来,我们会看到的
与其在列表变得太大时删除双表项,不如从一开始就不允许使用双表项?一种方法是将集合与某种索引组合在一起。
我通常使用的做法是有两个集合——一个用于数据,一个用于索引。
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速度减慢。
上面的代码显然不是线程安全的——这只是为了说明这一点。
http://msdn.microsoft.com/en-us/library/f7fta44c%28v=vs.90%29.aspx排序字典看起来是个不错的选择
一种解决方案是同时使用List和Dictionary。一开始就不把重复的项放在List中要比之后再去寻找它们容易得多。
使用您的Car示例:检查两个汽车在其属性的子集上是否相等,您需要一个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:(工作原理与Dictionary相同,除了它只保存键而不是键/值对)
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);
}