2013-06-07 4 views
27

मैं संग्रह से डुप्लिकेट निकालने में असमर्थ हूँ, मैं वर्ग कर्मचारी के लिए IEqualityComparer को लागू किया है अभी भी मैं नहीं उत्पादनकैसे IEqualityComparer का उपयोग कर संग्रह से डुप्लिकेट को निकालने के, LINQ अलग

static void Main(string[] args) 
    { 
     List<Employe> Employeecollection = new List<Employe>(); 

     Employeecollection.Add(new Employe("abc","def")); 
     Employeecollection.Add(new Employe("lmn","def")); 
     Employeecollection.Add(new Employe("abc", "def")); 

     IEnumerable<Employe> coll = Employeecollection.Distinct(new Employe()); 

     foreach (Employe item in coll) 
     { 
      Console.WriteLine(item.fName + " " + item.lName); 
     } 

    } 

नीचे हो रही है कर्मचारी वर्ग कार्यान्वयन, यहाँ मैं IEqualityComparer

class Employe : IEqualityComparer<Employe> 
{ 
    public string fName { get; set; } 
    public string lName { get; set; } 

    public Employe() 
    { 

    } 

    public Employe(string firstName, string LastName) 
    { 
     this.fName = firstName; 
     this.lName = LastName; 
    } 

    #region IEqualityComparer<pcf> Members 

    public bool Equals(Employe x, Employe y) 
    { 
     if (x.fName == y.fName && x.lName == y.lName) 
     { 
      return true; 
     } 

     return false; 
    } 

    public int GetHashCode(Employe obj) 
    { 
     return obj.GetHashCode(); 
    } 

    #endregion 
} 

उत्तर

79

भूल जाओ IEqualityComparer और बस सीधे Linq का उपयोग करें:

EmployeeCollection.GroupBy(x => new{x.fName, x.lName}).Select(g => g.First()); 
+0

यू के ऊपर एक मैं GroupBy को समझने समझाने कृपया लेकिन क्या करें है (छ => g.First() – Gun

+6

GroupBy आपरेशन आप वापस आ जाएगी [IGrouping] की एक IEnumerable (http://msdn.microsoft.com/en-us/library/bb344977.aspx) आइटम (जो IENumerables भी हैं)। आपके उदाहरण के मामले में, बाहरी IENumerable में दो आइटम होंगे: प्रत्येक IGrouping प्रत्येक के लिए दो प्रविष्टियों के साथ "एबीसी", "डीफ़"; "एलएमएन", "डीफ़" के लिए एक प्रविष्टि के साथ एक और IGrouping। पहला() ऑपरेटर आंतरिक IGrouping IENumerables से पहला आइटम लेगा। – avanek

+0

एकाधिक गुणों के साथ तर्क के लिए, आपको समूह करना होगा सभी गुणों पर जो xor तुलना की तुलना में धीमी गति से चलेंगे। –

4

कार्यान्वित आप अपने कर्मचारी में GetHashCode विधि ओवरराइड करने के लिए की जरूरत है। आपने यह नहीं किया है एक अच्छा हैशिंग विधि का एक उदाहरण नीचे दिया गया है (ReSharper द्वारा उत्पन्न)

public override int GetHashCode() 
{ 
    return ((this.fName != null ? this.fName.GetHashCode() : 0) * 397)^(this.lName != null ? this.lName.GetHashCode() : 0); 
} 

अब Distinct के बाद कहा जाता है, foreach पाश प्रिंट:

abc def 
lmn def 

अपने मामले में आप वस्तु की क्लास GetHashCode बुला रहे हैं, जो आंतरिक क्षेत्रों के बारे में कुछ भी नहीं जानता है।

IEnumerable<Employe> coll = 
Employeecollection.DistinctBy(employee => new {employee.fName, employee.lName}); 

बेनामी वस्तुओं दोनों GetHashCode और Equals तरीकों के लिए सही क्रियान्वयन हो:

एक साधारण नोट, MoreLINQDistinctBy विस्तार विधि है, जो आप करने की अनुमति देता में शामिल है।

5

यहाँ एक अच्छा tutorial

public int GetHashCode(Employe obj) 
    { 
     return obj.fname.GetHashCode()^obj.lname.GetHashCode(); 
    } 
+2

आपको समानता सदस्यों को लागू किए बिना गेटहाशकोड को कभी भी लागू नहीं करना चाहिए। GetHashCode भी एक ओवरराइड होना चाहिए। यह भी याद रखने योग्य है कि डेटा संरचनाओं में अनावश्यकता होने पर * "xor 'वितरण समस्याओं को बना या बढ़ा सकता है।" *: Http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines- और-gethashcode.aspx – spender

2

hashCode कार्यान्वयन है सही नहीं है:

public override int GetHashCode() 
{ 
    return 13 * fName.GetHashCode() + 7 * lName.GetHashCode(); 
} 
+1

के लिए नियम-नियम 'GetHashCode' में' NullReferenceException' प्राप्त करना ठीक है, जब ऑब्जेक्ट फ़ील्ड में से कोई एक शून्य है? –

+0

यह निश्चित रूप से नहीं है - मैंने सोचा कि मैं स्पष्ट कर सकता हूं कि "हैशकोड समान होने पर समान होना चाहिए" तथ्य, नल जांच पर ध्यान केंद्रित करने से। लेकिन हाँ, तुम सही हो। – aquaraga

-1
public int GetHashCode(Employe obj) 
{ 
    return obj.GetHashCode(); 
} 

इसके लिएविधि, गुणों के एक हैशकोड को वापस करें जिसे आप समानता के लिए तुलना कर रहे हैं, ऑब्जेक्ट के बजाए। ऑब्जेक्ट्स के हैशकोड की तुलना करना हमेशा false होगा, इसलिए आपकी सूची डुप्लिकेट के लिए फ़िल्टर नहीं की जाएगी।

0

यह भी सामग्री की बजाय संदर्भ द्वारा आपकी तुलना की तरह दिखता है, इसलिए तुलना फ़ंक्शन काम नहीं करता है।

इसे बदलने के लिए बदलें। == के बजाय एक्वाल्स() और इसे काम करना चाहिए। नीचे उदाहरण:

#region IEqualityComparer<pcf> Members 

public bool Equals(Employe x, Employe y) 
{ 
    if (x.fName.Equals(y.fName) && x.lName.Equals(y.lName)) 
    { 
     return true; 
    } 

    return false; 
} 

public int GetHashCode(Employe obj) 
{ 
    return obj.GetHashCode(); 
} 

#endregion 
+1

== ऑपरेटर सी # में तारों के लिए ठीक काम करता है। समस्या GetHashCode() कार्यान्वयन में है। – Fredrik

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