التحقق من التكرارات في المجموعة
سؤال
لنفترض أن لديك مجموعة من 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، ولكنه مع ذلك يستخدم ميزة الإصدار 3.5.لا مشكلة:
fooList.Exists(delegate(Foo Item) { return item.Bar == SomeBar});
يجب أن يعمل في 2.0.
نصائح أخرى
تنفيذ IEqualityComparer<T> الواجهة، واستخدام المطابقة يتضمن طريقة.
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() وتمرير المفوض الذي يُرجع صحيحًا لتعريفك لـ "المطابقة" (http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx).
يوجد مثال لكيفية تحديد المفوض في مستند MSDN هذا.
fooList.Exists(item => item.Bar == SomeBar)
أو مع مندوب مجهول
fooList.Exists(delegate(Foo item) {return item.Bar == SomeBar;})
إذا قمت بتجاوز Equals on Foo لإنشاء مفتاح على 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;
إذا كان بإمكانك استخدام LINQ، فيمكنك القيام بما يلي:
bool contains = foolist.Where(f => f.Bar == someBar).Count() != 0;
ربما تريد استخدام C5.HashSet، وتنفيذ Equals وGetHashCode() لـ Foo.