2009-09-08 7 views
36

मैं सोच रहा हूं कि सभी संस्कृतियों के लिए काम करने वाले मामले को अनदेखा करने वाले दो पात्रों की तुलना करने का सही तरीका क्या है। इसके अलावा, Comparer<char>.Default मामले को अनदेखा किए बिना दो वर्णों का परीक्षण करने का सबसे अच्छा तरीका है? क्या यह सरोगेट-जोड़े के लिए काम करता है?चार अनदेखी मामले की तुलना करने का सही तरीका क्या है?

संपादित: नमूना जोड़ा IComparer<char> कार्यान्वयन

इस किसी को भी मदद करता है यह मैं

public class CaseInsensitiveCharComparer : IComparer<char> { 
    private readonly System.Globalization.CultureInfo ci; 
    public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) { 
     this.ci = ci; 
    } 
    public CaseInsensitiveCharComparer() 
     : this(System.Globalization.CultureInfo.CurrentCulture) { } 
    public int Compare(char x, char y) { 
     return Char.ToUpper(x, ci) - Char.ToUpper(y, ci); 
    } 
} 

// Prints 3 
Console.WriteLine("This is a test".CountChars('t', new CaseInsensitiveCharComparer())); 
+0

toupper वर्तमान संस्कृति के संबंध में सही अपर केस को चार परिवर्तित कर सकते हैं, लेकिन शाब्दिक आदेश लौटा सही नहीं है। संभवतः यह केवल स्ट्रिंग तुलना के लिए .NET में समर्थित है। – Holstebroe

उत्तर

63

यह आप अल के लिए "काम से क्या मतलब है पर निर्भर करता है के लिए काम करेंगे एल संस्कृतियों "। क्या आप तुर्की में "मैं" और "मैं" बराबर होना चाहते हैं?

आप इस्तेमाल कर सकते हैं:

bool equal = char.ToUpperInvariant(x) == char.ToUpperInvariant(y); 

... लेकिन मुझे यकीन नहीं कर रहा हूँ कि क्या है कि "काम" "काम" की अपनी समझ से सभी संस्कृतियों के अनुसार।

बेशक आप दोनों पात्रों को तारों में परिवर्तित कर सकते हैं और फिर स्ट्रिंग पर जो भी तुलना चाहते हैं उसे निष्पादित कर सकते हैं।

bool equal = x.ToString().Equals(y.ToString(), 
           StringComparison.InvariantCultureIgnoreCase); 

सरोगेट जोड़े के लिए, एक Comparer<char> वैसे भी संभव होने के लिए नहीं जा रहा है, क्योंकि आप एक ही char नहीं है,: कुछ हद तक कम कुशल, लेकिन यह आप ढांचे में उपलब्ध तुलना की सभी रेंज देता है । हालांकि आप Comparer<int> बना सकते हैं।

+0

इस तरह मैं अपने उदाहरण के दोनों में यह कर के बारे में सोचा था, लेकिन सोचा था कि एक बेहतर तरीका है कि मैं ही अस्तित्व में है कि रूपरेखा प्रदान करता है पता नहीं था वहाँ गया हो सकता है है। मैं String.Contains के लिए LINQ विस्तार विधि के संदर्भ में सोच रहा था (चार, IEqualityComparer ) –

+1

इसके लिए कोई रूपरेखा विधि नहीं है: स्ट्रिंग तुलना वास्तव में देशी तरीकों का उपयोग कर कार्यान्वित किया जाता है, एक comparer कार्यान्वयन करने के लिए नीचे छोड़ने के द्वारा नहीं। –

+0

@TimSchmelter: नहीं, किसी कारण से इसे याद करने में कामयाब रहा। अंत में एक त्वरित नोट जोड़ा गया। –

1

string.Compare ("स्ट्रिंग एक" का उपयोग करने, "STRING ए 'क्या तय कर लिया है है, तो सच)

यह हर स्ट्रिंग

+1

हाय सर्जीओ, मैं दो चार उदाहरणों की तुलना करने के लिए एक तरीका है, स्ट्रिंग उदाहरण नहीं। मैं एक तुलनाकर्ता कार्यान्वयन की तलाश में हूं जो मामले को अनदेखा करता है। –

+8

यह अंग्रेजी भाषी देशों में बहुत अच्छा काम करता है। हालांकि, पूर्वी यूरोप में कोई भी आपके द्वारा लिखे गए एप्लिकेशन का उपयोग नहीं करेगा। –

+2

@Jon अनुदान: मैं अपने देश (पुर्तगाल) में इस का उपयोग, पुर्तगाली एक लैटिन आधारित भाषा की तरह "अजीब" वर्ण के बहुत सारे है कि है: एक é एक सी है, यह मेरे लिए पूरी तरह से काम करता है। – Sergio

12

डिफ़ॉल्ट का उपयोग करते हुए संस्कृति (कि नहीं अपरिवर्तनीय है):

if (char.ToLower(ch1) == char.ToLower(ch2)) 
{ .... } 

या एक संस्कृति निर्दिष्ट करें:

CultureInfo myCulture = ...; 
if (char.ToLower(ch1, myCulture) == char.ToLower(ch2, myCulture)) 
{ .... } 
+0

मैं डाउन-वोट नहीं कर सकता, लेकिन मैंने आपको एक वोट दिया क्योंकि मुझे लगता है कि आपका समाधान काफी उचित उत्तर दिया गया है। –

+0

यह प्रश्न का उत्तर नहीं है। –

+0

जॉन, सहमत हो गया लेकिन मैंने "सभी संस्कृतियों के लिए काम करेगा" को थोड़ा अधिक आशावादी और अवास्तविक के रूप में पढ़ा। मुझे स्पष्ट कहना चाहिए था। –

2

मैं इसे समझ, वहाँ वास्तव में एक तरीका है कि "सभी संस्कृतियों के लिए काम करेगा"। या तो आप किसी प्रकार के आंतरिक, गैर-प्रदर्शित-से-उपयोगकर्ता कारण के लिए वर्णों की तुलना करना चाहते हैं (इस मामले में आपको InvariantCulture का उपयोग करना चाहिए), या आप उपयोगकर्ता की CurrentCulture का उपयोग करना चाहते हैं। जाहिर है, उपयोगकर्ता की वर्तमान संस्कृति का उपयोग करने का अर्थ यह होगा कि आपको अलग-अलग इलाकों में अलग-अलग परिणाम मिलेंगे, लेकिन वे उन इलाकों में आपके उपयोगकर्ताओं की अपेक्षाओं के अनुरूप होंगे।

क्यों आप दो पात्रों की तुलना कर रहे हैं, इसके बारे में और जानने के बिना, मैं वास्तव में आपको सलाह नहीं दे सकता कि आपको किस का उपयोग करना चाहिए।

+0

धन्यवाद जॉन, यह एक सामान्य सवाल है, मैं यूनिकोड के साथ अच्छी तरह से नहीं जानता हूं और सोचा कि मैं यहां सवाल उठाऊंगा। String.Contains (चार, IEqualityComparer ) विस्तार विधि है कि LINQ प्रदान करता है पर विचार करें, क्या लागू करने के लिए सही तरीका होगा कि केस-संवेदी जा रहा है? –

+0

फिर से, यह वास्तव में इस बात पर निर्भर करेगा कि डेटा क्या था और आप इसकी तुलना क्यों कर रहे थे। यह आप चीजों को कुछ संगत क्रम में सॉर्ट करना चाहते थे उदाहरण के लिए, विभिन्न इन्वेंटियर तुलनाओं में से किसी एक का उपयोग करना ठीक होगा। यदि आप उपयोगकर्ता इनपुट का जवाब दे रहे हैं, तो संभवतः आप उस उपयोगकर्ता की संस्कृति का उपयोग उन परिणामों को देने के लिए करना चाहते हैं, जिनकी वे अपेक्षा करेंगे। मुझे यकीन नहीं है कि वास्तव में एक "एक आकार सभी फिट बैठता है" जवाब है। –

+0

क्या आपको लगता है कि मेरे तुलनात्मक कार्यान्वयन को उत्तर के रूप में प्रदान किया गया एक सही दृष्टिकोण होगा? –

0

आप की कोशिश कर सकते:

class Test{ 
    static int Compare(char t, char p){ 
     return string.Compare(t.ToString(), p.ToString(), StringComparison.CurrentCultureIgnoreCase); 
    } 
} 

लेकिन मुझे शक है इस "इष्टतम" जिस तरह से यह करने के लिए है, लेकिन मैं मामलों आप की जाँच करने की आवश्यकता के सभी नहीं कर रहा हूँ ...

0

क्या मैं सोच रहा था कि क्रम के भीतर उपलब्ध हो जाएगा निम्नलिखित

public class CaseInsensitiveCharComparer : IComparer<char> { 
    private readonly System.Globalization.CultureInfo ci; 
    public CaseInsensitiveCharComparer(System.Globalization.CultureInfo ci) { 
     this.ci = ci; 
    } 
    public CaseInsensitiveCharComparer() 
     : this(System.Globalization.CultureInfo.CurrentCulture) { } 
    public int Compare(char x, char y) { 
     return Char.ToUpper(x, ci) - Char.ToUpper(y, ci); 
    } 
} 

// Prints 3 
Console.WriteLine("This is a test".CountChars('t', new CaseInsensitiveCharComparer())); 
+1

यह मान लेना कि घटाव से चार तुलना भविष्य CLR संस्करणों में सही होना जारी रहेगा खतरनाक है, इसलिए मैं 'का प्रयोग करेंगे वापसी Char.ToUpper (एक्स, ci) .CompareTo (Char.ToUpper (y, ci));' बजाय । –

+0

@MattHowells मुझे लगता है कि लोगों का तर्क था ... कृपया 'देख char.CompareTo (चार)': 'वापसी (m_value-मूल्य);' –

0

की तरह कुछ मैं अपरकेस की तुलना की सिफारिश करेंगे है, और अगर वे फिर, छोटे की तुलना सिर्फ मामले लोकेल के uppercasing में मेल नहीं खाते और लोअरकेस तर्क थोड़ा अलग व्यवहार करते हैं।

परिशिष्ट

उदाहरण के लिए,

int CompareChar(char c1, char c2) 
{ 
    int dif; 

    dif = char.ToUpper(c1) - char.ToUpper(c2); 
    if (diff != 0) 
     dif = char.ToLower(c1) - char.ToLower(c2); 
    return dif; 
} 
संबंधित मुद्दे