То, что вы хотите, немного усложняется использованием TDictionary<string, TStringList>
, потому что это подразумевает переменное количество ключей.Если бы не переменное количество ключей, вам не понадобился бы словарь, и вы бы просто перебрали 3 TStringLists.
Тем не менее, у вас есть классическая проблема "генерировать все перестановки",Это можно решить с помощью рекурсии или возврата .Рекурсия проще в реализации, для возврата требуется меньше места в стеке.Выбор за вами.Вот полное консольное приложение, которое выполняет всю работу: от инициализации словаря, заполнения словаря до генерации всех перестановок с использованием рекурсивной функции.
program Project23;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, Generics.Collections;
var
Dict:TDictionary<string, TStringList>;
L: TStringList;
KeyName: string;
KeysList: TStringList;
// Help procedure, adds a bunch of values to a "Key" in the dictionary
procedure QuickAddToDict(KeyName:string; values: array of string);
var L: TStringList;
s: string;
begin
// Try to get the TStringList from the dictionary. If we can't get it
// we'll create a new one and add it to the dictionary
if not Dict.TryGetValue(KeyName, L) then
begin
L := TStringList.Create;
Dict.Add(KeyName, L);
end;
// Iterate over the values array and add stuff to the TStringList
for s in values do
L.Add(s);
end;
// Recursive routine to handle one KEY in the dictionary
procedure HandleOneKey(KeyIndex:Integer; PrevKeys:string);
var L:TStringList;
i:Integer;
Part: string;
KeyName: string;
begin
KeyName := KeysList[KeyIndex];
L := Dict[KeyName];
for i:=0 to L.Count-1 do
begin
Part := KeyName + '=' + L[i];
if KeyIndex = (KeysList.Count-1) then
WriteLn(PrevKeys + ' ' + Part) // This is a solution, we're at the last key
else
HandleOneKey(KeyIndex+1, PrevKeys + ' ' + Part); // Not at the last key, recursive call for the next key
end;
end;
begin
try
Dict := TDictionary<string, TStringList>.Create;
try
// Add whatever you want to the Dict.
// Using the helper routine to set up the dictionary faster.
QuickAddToDict('names', ['john', 'lisa', 'stan']);
QuickAddToDict('skills', ['read', 'write', 'speak']);
QuickAddToDict('ages', ['12', '14', '16']);
// Extract all the keys to a string list. Unfortunately the dictionary
// doesn't offer a way to get a key name by index, so we have to use the
// keys iterator to extract all keys first.
KeysList := TStringList.Create;
try
for KeyName in Dict.Keys do
KeysList.Add(KeyName);
if KeysList.Count > 0 then
begin
// We got at least one key, we can start the recursive process.
HandleOneKey(0, '');
end;
finally KeysList.Free;
end;
WriteLn;
WriteLn('Press ENTER to make the window go away');
ReadLn;
finally
// TDictionary doesn't own the keys or the values. Strings are managed types in
// delphi, we don't need to worry about them, but we do need to free the TStringList's
// We use the Values iterator for that!
for L in Dict.Values do
L.Free;
Dict.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.