检查集合中的重复项

本文关键字:集合 检查 | 更新日期: 2023-09-27 17:47:20

假设您有一个Foo类的集合:

class Foo
{
    public string Bar;
    public string Baz;
}
List<Foo> foolist;

并且您要检查此集合以查看另一个条目是否具有匹配的Bar

bool isDuplicate = false;
foreach (Foo f in foolist)
{
     if (f.Bar == SomeBar)
     {
         isDuplicate = true;
         break;
     }
}

Contains()不起作用,因为它比较了整个类。

没有人有更好的方法来做到这一点,适用于 .NET 2.0?

检查集合中的重复项

fooList.Exists(item => item.Bar == SomeBar)

这不是 LINQ,而是 Lambda 表达式,但它使用了 v3.5 功能。 没关系:

fooList.Exists(delegate(Foo Item) { return item.Bar == SomeBar});

这应该在 2.0 中工作。

实现 IEqualityComparer 接口,并使用匹配的包含方法。

public class MyFooComparer: IEqualityComparer<Foo> {
   public bool Equals(Foo foo1, Foo foo2) {
      return Equals(foo1.Bar, foo2.Bar);
   }
   public int GetHashCode(Foo foo) {
      return foo.Bar.GetHashCode();
   }
}
Foo exampleFoo = new Foo();
exampleFoo.Bar = "someBar";
if(myList.Contains(exampleFoo, new MyFooComparer())) {
    ...
}

如果需要该元素,还可以使用 List.Find() 并传入一个委托,该委托返回 true 用于定义"匹配"(http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx)。

有一个示例说明如何在该 MSDN 文档上定义委托。

fooList.Exists(item => item.酒吧 == 某条形)

或与匿名委托人

fooList.Exists(delegate(Foo item) {return item.酒吧 == 某条;})

如果你在Foo上覆盖Equals以在Bar上制作键,Contains()将起作用。

如果你的类的'Bar's是唯一的(类Foo的键),那么你可以尝试实现System.Collections.ObjectModel.KeyedCollection。 这很简单:只需实现 GetKeyForItem() 方法。

class Foo
{
    public string Bar;
    public string Baz;
}
class FooList : KeyedCollection<string, Foo>
{
    protected override string GetKeyForItem(Foo item)
    {
        return item.Bar;
    }
}
FooList fooList;

如果可以使用 LINQ,则可以执行以下操作:

bool contains = foolist.Where(f => f.Bar == someBar).Count() != 0;

以下是检查集合是否没有重复项的 4 种方法:

public static bool LinqAll<T>(IEnumerable<T> enumerable)
{
    HashSet<T> set = new();
    return !enumerable.All(set.Add);
}
public static bool LinqAny<T>(IEnumerable<T> enumerable)
{
    HashSet<T> set = new();
    return enumerable.Any(element => !set.Add(element));
}
public static bool LinqDistinct<T>(IEnumerable<T> enumerable)
{
    return enumerable.Distinct().Count() != enumerable.Count();
}
public static bool ToHashSet<T>(IEnumerable<T> enumerable)
{
    return enumerable.ToHashSet().Count != enumerable.Count();
}

您可能想使用 C5。HashSet,并为Foo实现Equals和GetHashCode()。