I have a case using TDictionary:
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;
Class TCustomEqualityComparer is copied from Generics Defaults TEqualityComparer (Delphi) with minor modification on GetHashCode method:
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;
I expect the TCustomEqualityComparer able to perform the case-insensitive matching for the key values. For example:
D.Items['TWO']
However, I get a "Item not found" exception. I am using Delphi 2010 Version 14.0.3513.24210.
Does anyone know how what's wrong with my code?
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;
The HashCode has to be the same for all values that return Equals = true! Try making Value uppercase in the GetHashCode before sending it to your HashFunction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With