Проверка на наличие дубликатов в коллекции - PullRequest
4 голосов
/ 25 сентября 2008

Предположим, у вас есть коллекция 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?

Ответы [ 8 ]

10 голосов
/ 25 сентября 2008
fooList.Exists(item => item.Bar == SomeBar)

Это не LINQ, а лямбда-выражение, но, тем не менее, оно использует функцию v3.5. Нет проблем:

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

Это должно работать в 2.0.

4 голосов
/ 25 сентября 2008

Реализация интерфейса IEqualityComparer и использование соответствующего метода 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())) {
    ...
}
0 голосов
/ 25 сентября 2008

Если вы можете использовать LINQ, вы можете сделать следующее:

bool contains = foolist.Where(f => f.Bar == someBar).Count() != 0;
0 голосов
/ 25 сентября 2008

Если вы переопределяете Equals на Foo для создания ключа на Bar, Contains () будет работать.

0 голосов
/ 25 сентября 2008

Если 'Bar для вашего класса уникальны (ключ к классу 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;
0 голосов
/ 25 сентября 2008

Если вам нужен элемент, вы также можете использовать List.Find () и передать делегат, который возвращает true для определения «соответствия» (http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx).

Есть пример того, как определить делегата в этом документе MSDN.

0 голосов
/ 25 сентября 2008

Возможно, вы захотите использовать C5.HashSet и реализовать Equals и GetHashCode () для Foo.

0 голосов
/ 25 сентября 2008

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

или с анонимным делегатом

fooList.Exists (делегат (элемент Foo) {return item.Bar == SomeBar;})

...