2012-05-17 14 views
18

के एक भाग के साथ छोड़कर मैं चारों ओर एक नज़र लिया है और यहाँ मदद करने के लिए कुछ भी नहीं मिल सकता है।सी # Linq एक दूसरे को काटना/वस्तु

class ThisClass 
{ 
    private string a {get; set;} 
    private string b {get; set;} 
} 

मैं इंटरसेक्ट और Linq के तरीकों को छोड़कर उपयोग करना चाहते हैं, यानी .:

private List<ThisClass> foo = new List<ThisClass>(); 
private List<ThisClass> bar = new List<ThisClass>(); 

तो मैं दो सूचियों अलग से भरने: मैं एक वर्ग मिल गया है। मैं उदाहरण के लिए, क्या करना चाहते हैं (और मैं जानता हूँ कि यह सही नहीं है, बस स्यूडोकोड है), निम्नलिखित:

foo[a].Intersect(bar[a]); 

मैं यह कैसे करना होगा?

किसी भी मदद के लिए धन्यवाद :)

+0

तुम क्या चाहते हो? शब्दों में समझाओ आप इस पंक्ति से क्या चाहते हैं 'foo [a]। अंतर (बार [ए]); '। –

उत्तर

25

शायद

// returns list of intersecting property 'a' values 
foo.Select(f => f.a).Intersect(bar.Select(b => b.a)); 

BTW संपत्ति a सार्वजनिक किया जाना चाहिए।

+0

अच्छा, सरल, बस मुझे जो चाहिए वह करता है। आप और सभी उत्तरदाताओं के लिए धन्यवाद। –

16

आप एक ही प्रॉपर्टी की एक सूची चाहते हैं तो आप तो एक दूसरे को काटना करने के लिए अन्य सभी सुंदर LINQ समाधान ठीक काम करना चाहते हैं। लेकिन! आप एक पूरे वर्ग पर हालांकि और इसके परिणामस्वरूप एक दूसरे को काटना चाहते हैं, तो एक List<ThisClass> बजाय List<string> की आप अपने खुद के समानता comparer लिखने के लिए होगा है।

foo.Intersect(bar, new YourEqualityComparer()); 

Except के साथ समान।

public class YourEqualityComparer: IEqualityComparer<ThisClass> 
{ 

    #region IEqualityComparer<ThisClass> Members 


    public bool Equals(ThisClass x, ThisClass y) 
    { 
     //no null check here, you might want to do that, or correct that to compare just one part of your object 
     return x.a == y.a && x.b == y.b; 
    } 


    public int GetHashCode(ThisClass obj) 
    { 
     unchecked 
     { 
      var hash = 17; 
          //same here, if you only want to get a hashcode on a, remove the line with b 
      hash = hash * 23 + obj.a.GetHashCode(); 
      hash = hash * 23 + obj.b.GetHashCode(); 

      return hash;  
     } 
    } 

    #endregion 
} 
-2

आपको IEqualityComparer बनाना चाहिए। आप IEqualityComparer को इंटरसेक्ट() विधि में पास कर सकते हैं। यह आपको सूची (जो बार के साथ छेड़छाड़) आसान पाने में मदद करेगा।

var intersectionList = foo.Intersect(bar, new ThisClassEqualityComparer()).ToList(); 


class ThisClassEqualityComparer : IEqualityComparer<ThisClass> 
{ 

    public bool Equals(ThisClass b1, ThisClass b2) 
    { 
     return b1.a == b2.a; 
    } 


    public int GetHashCode(Box bx) 
    { 
     // To ignore to compare hashcode, please consider this. 
     // I would like to force Equals() to be called 
     return 0; 
    } 

} 
+1

आपको इस तरह हैश कोड से '0' वापस नहीं लौटना चाहिए। यह पूरी तरह से प्रदर्शन को मारने जा रहा है। आपको इसके बजाय 'ए' के हैश कोड का उपयोग करना चाहिए। – Servy

0

वांछित प्रभाव वास्तव में क्या है? जब दो ThisClass उदाहरणों a की अनन्य मानों के माध्यम से पहचाने जाते हैं, आप अपनी कक्षाओं, या ThisClass की एक सूची में सभी a के से बना स्ट्रिंग की एक सूची प्राप्त करने के लिए करना चाहते हैं?

अगर यह पूर्व है, @lazyberezovksy और @Tilak से दो जवाब काम करना चाहिए।

private class ThisClass : IEquatable<ThisClass> 
{ 
    private string a; 

    public bool Equals(ThisClass other) 
    { 
     return string.Equals(this.a, other.a); 
    } 
} 

तो आप कॉल कर सकते हैं:

var intersection = foo.Intersect(bar);  
+1

'IEquatable' को लागू करते समय आपको हमेशा' GetHashCode' को ओवरराइड करने की आवश्यकता होती है। चूंकि आप नहीं करते हैं, यह काम नहीं करेगा। – Servy

3

के बारे में सुनिश्चित नहीं यदि यह उत्तरार्द्ध है, तो आप इतना है कि Intersect जानता है क्या ThisClass बराबर के दो उदाहरणों बनाता IEqualityComparer<ThisClass> या IEquatable<ThisClass> ओवरराइड करने के लिए होगा अंतर की तुलना में इसकी तुलना और तुलना करें लेकिन इसके बारे में कैसे:

//Intersect 
var inter = foo.Where(f => bar.Any(b => b.a == f.a)); 
//Except - values of foo not in bar 
var except = foo.Where(f => !bar.Any(b => b.a == f.a)); 
+3

यह एक ओ (एन * एम) एल्गोरिदम है जबकि 'इंटरसेक्ट' और 'एक्सेप्ट' दोनों 'ओ (एन + एम) 'हैं। इससे आपका बहुत बुरा हो जाता है। यह कई बार 'बार' को भी दोहराता है, जो सभी प्रकार की परिस्थितियों में एक बड़ी समस्या हो सकती है (यह प्रत्येक पुनरावृत्ति पर समान परिणाम नहीं दे सकती है, यह डेटाबेस से पूछताछ कर सकती है या प्रत्येक पुनरावृत्ति पर महंगी गणना को पूर्ववत कर सकती है, इसका दुष्प्रभाव हो सकता है जब पुनरावृत्त, आदि का कारण बनता है – Servy

0

मुझे पता है कि यह पुराना है लेकिन आप नहीं कर सकते बस वर्ग पर GetHashCode Equals & बराबर ओवरराइड करें?

class ThisClass 
{ 
    public string a {get; set;} 
    private string b {get; set;} 

    public override bool Equals(object obj) 
    { 
    // If you only want to compare on a 
    ThisClass that = (ThisClass)obj; 
    return string.Equals(a, that.a/* optional: not case sensitive? */); 
    } 

    public override int GetHashCode() 
    { 
    return a.GetHashCode(); 
    } 
} 
संबंधित मुद्दे