2012-02-15 19 views
7

ऐसे आइटमों को पोस्ट करने के लिए खेद है, मैं LINQ के लिए नया हूं और प्रत्येक IList के माध्यम से लूपिंग करने के लिए सबसे अच्छा तरीका जानने का प्रयास कर रहा हूं।किसी अन्य IList <>

मेरे पास कस्टम डीटीओ ऑब्जेक्ट्स के साथ 2 ILists<> है। मैं सभी मिलान करने वाली वस्तुओं को सूची में से हटाना चाहता हूं जो दूसरे में हैं।

IList<ItemDTO> list1 = itemsbl.GetBestItems(); 
IList<ItemDTO> list2 = itemsbl.GetWorstItems(); 

मैं list2 से list1 में सभी आइटम निकालने की जरूरत है। मैं Except() विधि देख रहा हूं लेकिन स्पष्ट रूप से मुझे GetHashCode और Equals कार्य करने के लिए विधियों को ओवरराइड करने के लिए मेरी ItemsDTO कक्षा की आवश्यकता है, लेकिन मुझे इसके कुछ उदाहरण खोजने में परेशानी हो रही है।

क्या कोई मुझे list1list2 से निकालने का सबसे अच्छा तरीका दिखा सकता है?

धन्यवाद फिर से

उत्तर

9

आप शायद विधि को छोड़कर उपयोग कर सकते हैं यह करने के लिए।

var newList = list2.Except(list1).ToList(); 

आप List2 तो बदलना चाहते हैं तो बस इस कार्य करें:

list2 = list2.Except(list1).ToList(); 

MSDN से:

कस्टम डेटा प्रकार की तुलना, IEquatable सामान्य इंटरफ़ेस को लागू और अपने खुद के प्रदान करने के लिए प्रकार के लिए GetHashCode और बराबर विधियां। डिफ़ॉल्ट समानता तुलनाकर्ता, डिफ़ॉल्ट, का उपयोग की तुलना करने के लिए किया जाता है जो IEquatable को लागू करता है।

+0

धन्यवाद, मैं तदनुसार मेरी कक्षा को संशोधित करने समाप्त हो गया तो यह है कि मैं हमें छोड़कर कर सकते हैं() ... आप हर किसी को धन्यवाद, मुझे यकीन है कि सभी अन्य समाधान बस के रूप में अच्छे थे ... हूँ:) – Nugs

1

यह निश्चित रूप से एक अच्छा तरीका हैश करें, @ जोन स्कीट एक समान प्रश्न के उत्तर के नीचे आपको समाधान प्रदान करेगा।

तो मूल रूप से वाक्य रचना है:

var setToRemove = new HashSet<ItemDTO>(list1); 
list2.RemoveAll(x => setToRemove.Contains(x)); 

Using LINQ to remove elements from a List<T>

उम्मीद है कि इस मदद करता है।

+0

मुझे नहीं पता क्यों, लेकिन RemoveAll() मेरे लिए एक विकल्प नहीं है ... – Nugs

+3

IList इंटरफ़ेस है जो सूची लागू करता है .लिस्ट अन्य संग्रह वर्गों के लिए उपयोग किया जाता है। सूची वर्ग में वे विधियां हैं जिन्हें IList में परिभाषित नहीं किया जा सकता है। तो ILI के लिए अपनी मूल सूची ऑब्जेक्ट असाइन करके आपको अब सूची के किसी भी अद्वितीय तरीके तक पहुंच नहीं होगी। जब तक आपके पास IList का उपयोग करने का कोई कारण नहीं है, तो मैं सूची का उपयोग करने की अनुशंसा करता हूं। एमएसडीएन: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx – Nickz

1
var list1 = new List<string> { "A", "B", "C" }; 
var list2 = new List<string> { "A", "C", "E", "B", "D", "G", "F" }; 
list2.RemoveAll(list1.Contains); 

भी काम करेगा। ध्यान दें कि सूची 1। सामग्री वास्तव में एक लैम्ब्डा

s => list1.Contains(s) 

-A।

+0

मुझे नहीं पता क्यों, लेकिन RemoveAll() मेरे लिए एक विकल्प नहीं है ... – Nugs

+0

'सूची। सामग्री' वास्तव में नहीं है एक लैम्ब्डा Althought यह वही व्यवहार करता है। – svick

+1

मैंने उल्लेख किया क्योंकि मैंने सोचा था कि RemoveAll एक अनुमान लगाता है, खासकर जब से ओपी की वस्तुओं में समानता/तुलना लागू नहीं होती है। – Ani

0

इसका अर्थ यह है कि आपको .NET रनटाइम को यह निर्धारित करने की आवश्यकता है कि कक्षा के दो उदाहरण बराबर हैं (उदाहरण के लिए यह कैसे परिभाषित किया जाना चाहिए कि आइटम डीटीओ का एक उदाहरण आइटम डीटीओ के किसी अन्य उदाहरण के बराबर है)।

ऐसा करने के लिए, ओवरराइड बराबर

public class ItemDTO 
{ 
    public override bool Equals(object obj) 
    { 
     var otherItem = obj as ItemDTO; 

     if (otherItem == null) 
     { 
      // this will be because either 'obj' is null or it is not of type ItemDTO. 
      return false; 
     } 

     return otherItem.SomeProperty == this.SomeProperty 
       && otherItem.OtherProperty == this.OtherProperty; 
    } 
} 

यदि आप ऐसा नहीं करते हैं, तो यह केवल सूची अन्य रूप में एक ही भौतिक उदाहरण के लिए जो बिंदु में किसी भी संदर्भ निकाल दिए जाएंगे। इसके बाद आप एक्सेप्ट या निकालें सभी विधियों या आप जिस भी अन्य विधि का उपयोग करने का निर्णय लेते हैं उसका उपयोग कर सकते हैं।

आपको GetHashcode को ओवरराइड करने की भी आवश्यकता होगी, उस पर और जानकारी के लिए नीचे दिए गए लिंक को देखें।

देखें Guidelines for Overloading Equals and GetHashcode

संबंधित मुद्दे