مقارنة قائمتين ، حيث لا يهم النظام ، وذلك باستخدام IEqualityComparer

أرغب في التحقق مما إذا كانت قائمتان تحتويان على نفس العناصر. لا يهم ترتيب العناصر ، وقد تظهر العناصر نفسها مرتين في كل قائمة.

فمثلا:

var List1 = new List { 1, 2, 2 };
var List2 = new List { 2, 1, 2 };
//equal

var List1 = new List { 1, 2, 2 };
var List2 = new List { 2, 1, 1 };
//not equal - different quantities of 1s and 2s in the two lists

حاليا أفعل هذا على النحو التالي:

var List2copy = List2.ToList();
if (List1.Count != List2.Count) return false;
return List1.All(x => List2copy.Remove(x));

Now however I need to use an IEqualityComparer for the two items, which Remove cannot accept. Can anyone think of an efficient solution for the problem? It would also be useful if it accepted an IEnumerable rather than a List

0
تضمين التغريدة أنا تماما TL ، DR'd ذلك! اعتذاري!
وأضاف المؤلف series0ne, مصدر
وأضاف المؤلف series0ne, مصدر
YairHalberstadt لست متأكدًا من مقارنة مجموعات التجزئة بالطريقة الصحيحة للتقدم ، لأن {2، 2، 1} و {1، 1، 2} تعتبر متساوية.
وأضاف المؤلف series0ne, مصدر
هل يمكنك طلب القوائم أولاً؟ بعد ذلك ، يمكنك إجراء SequenceEqual بشكل طبيعي ؟
وأضاف المؤلف RB., مصدر
AsakuraaRanger لن يعمل هذا إذا كان هناك أكثر من عنصر واحد مطابق
وأضاف المؤلف Yair Halberstadt, مصدر
@ series0ne إنه القسم المختلف لذلك الجواب القابل للتطبيق
وأضاف المؤلف Yair Halberstadt, مصدر
VanVO كلا. لا يعمل هذا إلا إذا لم يتساوى عنصرين في نفس القائمة
وأضاف المؤلف Yair Halberstadt, مصدر
RB ليس بسهولة. إنها كائنات معقدة للغاية ، تحتوي على قوائم فرعية ، والتي يجب أن يتم فرزها أولاً للتأكد من أن الطلب سيكون هو نفسه. أنا أفضل تجنب ذلك إن أمكن.
وأضاف المؤلف Yair Halberstadt, مصدر
@ RenéVogt يقوم IEqualityComparer بالكثير من العمل - إنه في الواقع يقارن بين القوائم الفرعية في الجسمين بالطريقة نفسها بالفعل ، لذا فإن ترتيبها يتطلب فرز كل القوائم الفرعية أيضًا. قد يكون هذا مكلفًا. أنا على أمل أنه قد يكون هناك طريقة أبسط.
وأضاف المؤلف Yair Halberstadt, مصدر
@ series0ne أعتقد أن الرد الرابع قد يكون قابلاً للتطبيق ، وإن كان قبيحًا. التحقق من ذلك.
وأضاف المؤلف Yair Halberstadt, مصدر
YairHalberstadt - عند طرح سؤال ، من الجيد أن يكون لديك رمز على الأقل.
وأضاف المؤلف Enigmativity, مصدر
استخدم تتقاطع التي تأخذ أيضًا IEqualityComparer . يمكن حل آخر تحويل كل قائمة إلى قاموس حيث سيكون مفتاح مكافئ للعنصر وقيمة عدد العناصر التي تظهر في القائمة. في وقت لاحق يمكنك مقارنة كل من القواميس.
وأضاف المؤلف user1672994, مصدر
أعتقد أن هذا يناسب احتياجاتك stackoverflow.com/الأسئلة/12795882/و hellip؛
وأضاف المؤلف Van VO, مصدر
stackoverflow.com/questions/12795882/&hellip؛ ألق نظرة على هذا
وأضاف المؤلف Asakuraa Ranger, مصدر
@ R.García لن تعمل بسبب المثال الأول.
وأضاف المؤلف Tanveer Badar, مصدر
لماذا لا تستخدم طريقة .Contains() للمجموعة ( قائمة <>
وأضاف المؤلف R. García, مصدر

4 إجابة

يجب أن يعمل هذا:

var List2copy = List2.ToList();
if (List1.Count != List2.Count) return false;
return List1.All(x =>
{
    int index = List2copy.FindIndex(y => new MyEqualityComparer().Equals(x, y));
    if (index == -1) return false;
    List2copy.RemoveAt(index);
    return true;
});
0
وأضاف

خيار آخر يمكنك تجربته هو:

var lookup1 = List1.ToLookup(x => x);
var lookup2 = List2.ToLookup(x => x);

return lookup1.Count == lookup2.Count && lookup1.All(x => lookup2[x.Key].SequenceEqual(x));

هذا لا يتطلب فرزًا كاملاً وقد يعرض النتائج بسرعة أكبر.

0
وأضاف
ماذا لو كانت List2 تحتوي على مفاتيح أكثر من List1 ، فستحتاج إلى التحقق من كلتا الطريقتين.
وأضاف المؤلف Lasse Vågsæther Karl, مصدر
@ LasseVågsætherKarlsen - نقطة ممتازة. إنه حل أفضل الآن مع مقارنة .Count بسيطة في البداية. لا معنى للشروع في المتابعة ما لم تكن هي نفسها.
وأضاف المؤلف Enigmativity, مصدر

جرب هذا يجب أن تعمل لحالتك:

return ListA.OrderBy(x => x).SequenceEqual(ListB.OrderBy(x => x));

مجرد أمر مؤقت ثم قارن

0
وأضاف

الحل الذي يمكنك استخدامه ربما هو:

  1. أنشئ قائمتين بقيم مميزة للقوائم الأصلية.
  2. يتقاطع مع قائمتي القيمتين المتميزتين في قائمة واحدة تحتوي على جميع القيم المميزة.
  3. لكل عنصر في قائمة القيم المميزة المجمعة ، احسب مقدار التكرارات في كل قائمة أصلية

الشفرة:

var list1 = new List{1,2,2};
var list2 = new List{1,1,2};
var list1Distinct = list1.Distinct();
var list2Distinct = list1.Distinct();
var allDistinctValues = list1.Intersect(list2);
bool listsEqual = true;

foreach(int i in allDistinctValues)
{
    int list1Count=0;
    int list2Count=0;
    list1Count = list1.Count(val => val == i);
    list2Count = list2.Count(val => val == i);
    if(list1Count != list2Count)
    {
        listsEqual = false;
    }
}

if(!listsEqual)
{
    //List item counts not the same
}
0
وأضاف