2009-10-23 8 views
9

मैं का उपयोग कर एक मामला है TDictionary:TDictionary के लिए संवेदनशील-संवेदनशील TEqualityComparer में कोई केस कैसे बनाएं?

var D: TDictionary<string, integer>; 
begin 
    D := TDictionary<string, integer>.Create(TCustomEqualityComparer.Create()); 
    try 
    D.Add('One', 1); 
    D.Add('Two', 2); 
    D.Add('Three', 3); 

    showmessage(inttostr(D.Items['One'])); 
    showmessage(inttostr(D.Items['TWO'])); 
    finally 
    D.Free; 
    end; 
end; 

कक्षा TCustomEqualityComparer GetHashCode विधि पर मामूली संशोधन के साथ Generics Defaults TEqualityComparer (Delphi) से नकल है:

TCustomEqualityComparer = class(TEqualityComparer<string>) 
public 
    function Equals(const Left, Right: string): Boolean; override; 
    function GetHashCode(const Value: string): Integer; override; 
end; 

function TCustomEqualityComparer.Equals(const Left, Right: string): Boolean; 
begin 
    Result := SameText(Left, Right); 
end; 

function TCustomEqualityComparer.GetHashCode(const Value: string): Integer; 
begin 
    Result := BobJenkinsHash(Value[1], Length(Value) * SizeOf(Value[1]), 0); 
end; 

मैं उम्मीद TCustomEqualityComparer लिए केस-संवेदी मिलान प्रदर्शन करने में सक्षम महत्वपूर्ण मूल्य उदाहरण के लिए:

D.Items['TWO'] 

हालांकि, मुझे "आइटम नहीं मिला" अपवाद मिलता है। मैं डेल्फी 2010 संस्करण 14.0.3513.24210 का उपयोग कर रहा हूँ।

क्या कोई जानता है कि मेरे कोड में क्या गलत है?

उत्तर

2

धन्यवाद। मैं TCustomEqualityComparer.GetHashCode बदल दिया है और यह काम करता है के रूप में आप ने कहा:

function TCustomEqualityComparer.Equals(const Left, Right: string): Boolean; 
begin 
    Result := SameText(Left, Right); 
end; 

function TCustomEqualityComparer.GetHashCode(const Value: string): Integer; 
var s: string; 
begin 
    s := UpperCase(Value); 
    Result := BobJenkinsHash(s[1], Length(s) * SizeOf(s[1]), 0); 
end; 
3

हैशकोड को सभी मानों के लिए समान होना चाहिए जो समान = सत्य लौटाते हैं! GetHashCode में इसे अपने हैश फ़ंक्शन पर भेजने से पहले वैल्यू अपरकेस बनाने का प्रयास करें।

+0

क्या आप वाकई मूल के बराबर है पहले से ही केस-संवेदी है? यह यूनिट जेनिक्स में परिभाषित मूल बराबर विधि है। डिफॉल्ट.pas: फ़ंक्शन Equals_UString (इंस्टेंट: PSimpleInstance; कॉन्स्ट बाएं, दाएं: यूनिकोडस्ट्रिंग): बूलियन; प्रारंभ करें परिणाम: = बाएं = दाएं; अंत; –

+0

आप सही हैं! मैंने मूल कार्यान्वयन और एक उदाहरण मिलाया। –

12
uses System.Generics.Collections, System.Generics.Defaults; 

var 
    D: TDictionary<string, Integer>; 
begin 
    D := TDictionary<string, Integer>.Create(TIStringComparer.Ordinal); // ‹- this is the trick 
    try 
    D.Add('One', 1); 
    . 
    . 
    finally 
    D.Free; 
    end; 
end; 
संबंधित मुद्दे