Can I prevent TStringList from removing key-value-pair when value is set to empty? I use Delphi XE8 and Lazarus which work differently. I want the pair to be left in the TStringlist object even when the value is set to an empty string. For example:
procedure TMyClass.Set(const Key, Value: String);
begin
// FData is a TStringList object
FData.Values[Key] := Value; // Removes pair when value is empty. Count decreases and Key is lost.
end;
Problem that I'm having is that when I compile with Delphi the pair with empty values is removed and I don't know afterwards was a value with a key never set or was it explicitly set to be an empty string. Also I can't get all the keys that have been used. Now I need to hold another collection of keys that holds information about empty ones.
MyKeyValues.Set('foo', 'bar'); // Delphi FData.Count = 1; Lazarus FData.Count = 1
MyKeyValues.Set('foo', ''); // Delphi FData.Count = 0; Lazarus FData.Count = 1
You can use a TStringList to store Key-Value pairs. This can be useful if you want to store settings, for example. A settings consists of a Key (The Identifier of the setting) and the value. Each Key-Value pair is stored in one line of the StringList in Key=Value format.
A settings consists of a Key (The Identifier of the setting) and the value. Each Key-Value pair is stored in one line of the StringList in Key=Value format.
TStringList has a variety of user cases including string manipulation, sorting, indexing, key-value pairing and delimiter separation among them. You can use a TStringList to store Key-Value pairs. This can be useful if you want to store settings, for example. A settings consists of a Key (The Identifier of the setting) and the value.
In this example, the Stringlist has the following content before it is destroyed: Under the hood TStringList performs key search by straight looping through all items, searching for separator inside every item and comparing the name part against the given key.
You can write a class helper to implement a new behaviour of the SetValue
method of the TStrings
class.
If you don't like a solution based on a class helper, you can use a custom class which inherits from TStringList
and, again, override its Values
property behaviour - the code is very similar to this helper-based implementation.
I'd prefer to use the second choice because the helper will define a new behaviour for all the TStringList
objects.
type
TStringsHelper = class helper for TStrings
private
function GetValue(const Name: string): string;
procedure SetValue(const Name, Value: string); reintroduce;
public
property Values[const Name: string]: string read GetValue write SetValue;
end;
function TStringsHelper.GetValue(const Name: string): string;
begin
Result := Self.GetValue(Name);
end;
procedure TStringsHelper.SetValue(const Name, Value: string);
var
I: Integer;
begin
I := IndexOfName(Name);
if I < 0 then I := Add('');
Put(I, Name + NameValueSeparator + Value);
end;
What about this?
procedure TMyClass.Set(const Key, Value: String);
var
i:integer;
begin
i := FData.IndexOfName(Key);
if i = -1 then
FData.Add(Key + '=' + Value)
else
FData[i] := Key + '=' + Value;
end;
You can choose wether to set FData.Sorted:=true;
or not.
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