delphi字典迭代 [英] delphi dictionary iterating
问题描述
早上好!
i用字符串作为值和几个字符串作为值填充字典TDictionary<String, TStringlist>
(delphi-collections-unit).
像这样:
i fill a dictionary TDictionary<String, TStringlist>
(delphi-collections-unit) with strings as values and several strings as values.
something like:
- 名称=约翰,丽莎,斯坦
- 技能=读写,说话
- 年龄= 12、14、16
(当然不带,"). 我需要的是迭代此字典,并用键乘出值. 输出应该像
(without "," of course). what i need is to iterate this dictionary and to multiply out the values with the keys. output should be like
- 姓名=约翰技能=阅读年龄= 12
- 姓名=约翰技能=阅读年龄= 14
- 姓名=约翰技能=阅读年龄= 16
- 姓名=约翰技能=写年龄= 12
- 姓名=约翰技能=写年龄= 14
- 姓名=约翰技能=写年龄= 16
- ...
- 名称= lisa技能=阅读年龄= 12
- ...
- 姓名=基本技能=说话年龄= 16
- names = john skills = read ages = 12
- names = john skills = read ages = 14
- names = john skills = read ages = 16
- names = john skills = write ages = 12
- names = john skills = write ages = 14
- names = john skills = write ages = 16
- ...
- names = lisa skills = read ages = 12
- ...
- names = stan skills = speak ages = 16
所以每个组合. 我该怎么办?键的数量是动态的,字符串列表的大小也是动态的. 谢谢!现在解决了...
so every combination. how can i do so? the number of keys is dynamic and so is the size of the tstringlist. thanks! SOLVED by now...
现在示波器存在问题.以下是填充字典的过程.子内容和splitstring是字符串列表,在过程结束时将其释放. dict是在procedures-block之后创建的(主要是?它是怎么被调用的?),fill方法被调用,然后我想像代码示例中那样进行递归,但是dict中没有值...
now the problem with the scope. following is the procedure that fills the dict. the subsplits and the splitstring are stringlists, that get freed at the end of the procedure. the dict is created after the procedures-block (in main? how is it called?), the fill-method is called and then i want to do recursion like in the code-example but there are no values in the dict....
while not Eof(testfile) do
begin
ReadLn(testfile, text);
if AnsiContainsStr(text, '=') then
begin
Split('=', text, splitarray);
splitarray[0] := trim(splitarray[0]);
splitarray[1] := DeleteSpaces(splitarray[1]);
if AnsiStartsStr('data', splitarray[0]) then
begin
split(' ', splitarray[0], subsplit1);
splitarray[0]:=subsplit1[1];
split(',', splitarray[1], subsplit2);
dict.Add(splitarray[0], subsplit2);
for ValueName in dict.Values do
begin
for i := 0 to Valuename.Count - 1 do
write('Values are : '+ Valuename[i]);
writeln;
end;//
end;//
end;//
end;//
推荐答案
使用TDictionary<string, TStringList>
会使所需的操作变得有些复杂,因为这意味着键的数量可变.如果不是用于可变数量的键,则不需要字典,只需遍历3个TStringList.
What you want is made a bit complicated by the use of the TDictionary<string, TStringList>
, because that implies variable number of keys. If it weren't for the variable number of keys, you wouldn't need a dictionary and you'd simply iterate over 3 TStringLists.
也就是说,您遇到了经典的生成所有排列"问题.可以使用递归或回溯来解决.递归更易于实现,回溯使用更少的堆栈空间.这是你的选择.这是一个完整的控制台应用程序,可以完成所有工作,从初始化字典,填充字典到使用递归函数生成所有排列.
That said, you've got the classic "generate all permutations" problem. It can be solved using recursion or backtracking. Recursion is simpler to implement, backtracking uses less stack space. The choice is yours. Here's a complete console application that does the whole deal, from initializing the dictionary, populating the dictionary, generating all permutations using a recursive function.
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.
这篇关于delphi字典迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!