Reputation: 175733
Suppose you have a collection of Foo
classes:
class Foo
{
public string Bar;
public string Baz;
}
List<Foo> foolist;
And you want to check this collection to see if another entry has a matching Bar
.
bool isDuplicate = false;
foreach (Foo f in foolist)
{
if (f.Bar == SomeBar)
{
isDuplicate = true;
break;
}
}
Contains()
doesn't work because it compares the classes as whole.
Does anyone have a better way to do this that works for .NET 2.0?
Upvotes: 4
Views: 1449
Reputation: 4839
Here are 4 ways to check if the collection has no duplicates:
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();
}
Upvotes: 0
Reputation:
If you can use LINQ you can do the following:
bool contains = foolist.Where(f => f.Bar == someBar).Count() != 0;
Upvotes: 0
Reputation: 416159
If the 'Bar's for your class are unique (a key to class Foo), then you can try implementing a System.Collections.ObjectModel.KeyedCollection. It's pretty simple: just implement the GetKeyForItem() method.
class Foo
{
public string Bar;
public string Baz;
}
class FooList : KeyedCollection<string, Foo>
{
protected override string GetKeyForItem(Foo item)
{
return item.Bar;
}
}
FooList fooList;
Upvotes: 0
Reputation: 34710
Implement the IEqualityComparer<T> interface, and use the matching Contains method.
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())) {
...
}
Upvotes: 4
Reputation: 50245
If you override Equals on Foo to make key on Bar, Contains() will work.
Upvotes: 0
Reputation: 1527
fooList.Exists(item => item.Bar == SomeBar)
or with anonymous delegate
fooList.Exists(delegate(Foo item) {return item.Bar == SomeBar;})
Upvotes: 0
Reputation: 103605
fooList.Exists(item => item.Bar == SomeBar)
That's not LINQ, but a Lambda expression, but nevertheless, it uses a v3.5 feature. No problem:
fooList.Exists(delegate(Foo Item) { return item.Bar == SomeBar});
That should work in 2.0.
Upvotes: 10
Reputation: 356044
If you need the element, you can also use List.Find() and pass in a delegate that returns true for your definition of a "match" (http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx).
There's an example of how to define a delegate on that MSDN doc.
Upvotes: 0
Reputation: 230396
You probably want to use C5.HashSet, and implement Equals and GetHashCode() for Foo.
Upvotes: -1