Mega Search
23.2 Million


Sign Up

Make a donation  
Tdictionary case sensitive?  
News Group: embarcadero.public.delphi.language.delphi.general

DXE:
I think that Tdicionary key values are case sensitive - which is a bit of a 
surprise.
Though I can cope with it, it there a property that I missed to make them 
case-insensitive?
Tom

Vote for best question.
Score: 0  # Vote:  0
Date Posted: 19-Jul-2011, at 1:29 PM EST
From: Tom deNeef
 
Re: Tdictionary case sensitive?  
News Group: embarcadero.public.delphi.language.delphi.general
Tom deNeef wrote:

> DXE:
> I think that Tdicionary key values are case sensitive - which is a
> bit of a surprise.

It is case sensitive.

> Though I can cope with it, it there a property
> that I missed to make them case-insensitive?

No there isn't a property, because it is a general purpose dictionary.
What you can do is to implement a case insensitive version of the
IEqualityComparer interface.

{code}
program Project109;

{$APPTYPE CONSOLE}

uses
  SysUtils, Generics.Collections, Generics.Defaults;

type
  TStringEqualityComparer = class(TInterfacedObject, 
    IEqualityComparer)
    function Equals(const Left, Right: string): Boolean;
    function GetHashCode(const Value: string): Integer;
  end;

{ TStringEqualityComparer }

function TStringEqualityComparer.Equals(const Left, Right: string):
Boolean;
begin
  Result := CompareText(Left, Right) = 0;
end;

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

var
  D: TDictionary;
begin
  D := TDictionary.Create
    (TStringEqualityComparer.Create);
  try
    D.Add('A', 1);
    
    { should raise EListError with message 'Duplicates not allowed'
      when case insensitive }
    D.Add('a', 2);

    D.Add('B', 3);
  finally
    D.Free;
  end;
end.
{code} 
-- 
Uwe Schuster
http://www.bitcommander.de/blog

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 19-Jul-2011, at 2:01 PM EST
From: Uwe Schuster
 
Re: Tdictionary case sensitive?  
News Group: embarcadero.public.delphi.language.delphi.general
> function TStringEqualityComparer.Equals(const Left, Right: string):
> Boolean;
> begin
>   Result := CompareText(Left, Right) = 0;
> end;

A minor correction, but you should probably pass loUserLocale as a second
parameter too. Either that or call AnsiCompareText,* which is all
loUserLocale does, otherwise something like 'café' and 'CAFÉ' won't be
considered equal.

>   S := AnsiLowerCase(Value);

* ... like you've done here in fact.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 19-Jul-2011, at 2:36 PM EST
From: Chris Rolliston
 
Re: Tdictionary case sensitive?  
News Group: embarcadero.public.delphi.language.delphi.general
"Uwe Schuster"  schreef in bericht 
news:379218@forums.embarcadero.com...
> Tom deNeef wrote:
>
>> DXE:
>> I think that Tdicionary key values are case sensitive - which is a
>> bit of a surprise.
>
> It is case sensitive.
>
>> Though I can cope with it, it there a property
>> that I missed to make them case-insensitive?
>
> No there isn't a property, because it is a general purpose dictionary.
> What you can do is to implement a case insensitive version of the
> IEqualityComparer interface.
>
> {code}
> program Project109;
>
> {$APPTYPE CONSOLE}
>
> uses
>  SysUtils, Generics.Collections, Generics.Defaults;
>
> type
>  TStringEqualityComparer = class(TInterfacedObject,
>    IEqualityComparer)
>    function Equals(const Left, Right: string): Boolean;
>    function GetHashCode(const Value: string): Integer;
>  end;
>
> { TStringEqualityComparer }
>
> function TStringEqualityComparer.Equals(const Left, Right: string):
> Boolean;
> begin
>  Result := CompareText(Left, Right) = 0;
> end;
>
> function TStringEqualityComparer.GetHashCode(const Value: string):
> Integer;
> var
>  S: string;
> begin
>  S := AnsiLowerCase(Value);
>  Result := BobJenkinsHash(S[1], Length(S) * SizeOf(S[1]), 0);
> end;
>
> var
>  D: TDictionary;
> begin
>  D := TDictionary.Create
>    (TStringEqualityComparer.Create);
>  try
>    D.Add('A', 1);
>
>    { should raise EListError with message 'Duplicates not allowed'
>      when case insensitive }
>    D.Add('a', 2);
>
>    D.Add('B', 3);
>  finally
>    D.Free;
>  end;
> end.
> {code}

Thank you. This will move me into a part of the laguage that I have no 
experience with.
I will define a descendant of my particular Tdictionary and override the Add 
and tryGetValue methods (where the strings will be transformed to 
uppercase).
Tom

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 20-Jul-2011, at 6:03 AM EST
From: Tom deNeef
 
Re: Tdictionary case sensitive?  
News Group: embarcadero.public.delphi.language.delphi.general
> Thank you. This will move me into a part of the laguage that I have no 
> experience with.
> I will define a descendant of my particular Tdictionary and override the Add 
> and tryGetValue methods (where the strings will be transformed to uppercase).
> Tom

haha like me :)
by the way we have to learn..

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 20-Jul-2011, at 12:39 PM EST
From: Mehmet Fide