tags:

views:

260

answers:

3

I have a lot of constants that are somehow related, at some point I need to pair them, something like this:

const
  key1 = '1';
  key2 = '2';
  key3 = '3';

  value1 = 'a';
  value2 = 'b';
  value3 = 'c';

I want to avoid doing:

if MyValue = key1 then Result := value1;

I know how to do it with string lists using:

MyStringList.Add(key1 + '=' + value1);
Result := MyStringList.Values[key1];

But, is there any simpler way to do this?

+8  A: 

Yes, assignment can be done this way instead, avoiding manual string concatenation:

MyStringList.Values[Key1] := Value1;
Jozz
Using Values/Names of a StringList can be a speed problem. When using that method, all searches are linear, event if you sort your list. If you have a small amount of data there, it's ok. But for large amount, avoid that technique
vIceBerg
Thanks, I've forgotten this way. But there is another way without using StringLists?
Fabio Gomes
THashedStringList uses an internal hashed list for speed
Jeff Cuscutis
Wow, I had never seen THashedStringList before. Good to know! Thanks, Jeff.
Jozz
One thing to be aware of is the the THashedStringList is great for lists that don't change much, but probably not the best for volatile lists.
Jeff Cuscutis
Yes, THashedStringList invalidates the hash array every time the list changes.
Jozz
+4  A: 

Do a wrapper around your "value"

TMyValue = class
  value: String;
end;
Then use this:
myValue := TMyValue.Create;
myValue.Value = Value1;

MyStringList.AddObject(Key1, Value1);

Then, you can sort your list, do a IndexOf(Key1) and retrieve the object.

That way, your list is sorted and the search is very fast.

vIceBerg
A: 

You can use a multi-dimensional constant array with an enumeration for at least one of the dimensions:

Define it like this:

type
  TKVEnum = (tKey, tValue); // You could give this a better name
const
  Count = 3;
  KeyValues: array [1..Count, TKVEnum] of string =
    // This is each of your name / value paris
    (('1', 'a'), ('2', 'b'), ('3', 'd'));

Then you use it like this:

if MyValue = KeyValues[1, TKVEnum.tKey] then 
  Result := KeyValues[1, TKVEnum.tValue]

You could use a For loop on it too. This is just as efficient as doing them as individual constant strings, but gives you the added advantage that they are intrinsically associated.

Instead of defining the first dimension numerically, I would suggest

type
  TConstPairs = (tcUsername, tcDatabase, tcEtcetera);

But I guess that totally depends on what you constants represent.

Jim McKeeth