检查集合中的重复项

时间:2020-03-06 14:44:05  来源:igfitidea点击:

假设我们有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)

或者与匿名代表

fooList.Exists(delegate(Foo item){返回item.Bar == SomeBar;})

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

实现IEqualityComparer <T>接口,并使用匹配的Contains方法。

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()并传入一个对" match"定义返回true的委托(http://msdn.microsoft.com/zh-cn/library/x0b5b5bc。 aspx)。

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

如果班级的"酒吧"是唯一的(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;

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

那不是LINQ,而是Lambda表达式,但尽管如此,它仍使用v3.5功能。没问题:

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

那应该在2.0中起作用。

如果我们覆盖Foo上的Equals以在Bar上生成键,则Contains()将起作用。

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

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