2009-10-23 8 views
9

kullanıyorum bir durum var TDictionary:TDictionary için hassas bir TEqualityComparer vakası nasıl oluşturulur?

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; 
Sınıf TCustomEqualityComparer GetHashCode yöntemi üzerinde küçük değişiklikler yapılarak Generics Defaults TEqualityComparer (Delphi) kopyalanır

:

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; 

beklediğim için küçük harf duyarsız eşleştirme için TCustomEqualityComparer mümkün anahtar değerler. Örneğin, "Öğe bulunamadı" istisnası alıyorum. Delphi 2010 Sürüm 14.0.3513.24210 kullanıyorum.

Kodumda neyin yanlış olduğunu bilen var mı?

cevap

2

Teşekkürler. Ben TCustomEqualityComparer.GetHashCode değişti ve dediğin gibi çalışır:

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

HashCode, Equals = true döndüren tüm değerler için aynı olmalıdır! GetHashCode'da HashFunction öğesine göndermeden önce Value büyük harfini oluşturmayı deneyin.

+0

özgün zaten küçük harfe duyarlı değildir Eşittir emin misin? Bu, Birim Generics.Defaults.pas biriminde tanımlanan orijinal Eşittir yöntemi: işlevi Equals_UString (Inst: PSimpleInstance; const Sol, Sağ: UnicodeString): Boolean; başlamak Sonuç: = Sol = Sağ; sonu; –

+0

Haklısınız! Orijinal uygulamayı ve bir örneği karıştırdım. –

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; 
İlgili konular