如何使用TEnumerator按键对我的TDictionary进行排序?
我有这样的事情:
var
Dic: TDictionary<string, string>;
Enum: TPair<string, string>;
begin
Dic := TDictionary<string, string>.create;
Dic.Add('Tired', 'I have been working on this too long');
Dic.Add('Early', 'It is too early in the morning to be working on this');
Dic.Add('HelpMe', 'I need some help');
Dic.Add('Dumb', 'Yes I know this example is dumb');
{ I want to do the following but do it in sorted order by Enum.Key }
for Enum in Dic do
some processing with Enum.Key and Enum.Value;
Dic.Free;
end;
因此,我想按以下顺序处理字典:哑巴,早期,HelpMe,累了。
不幸的是,Delphi帮助在描述一般枚举器和TEnumerator的工作原理时非常微不足道,并且没有提供我可以找到的示例。在Web上,关于在Delphi中将枚举数与泛型一起使用的信息也很少。
而且我上面的示例代码甚至没有使用TEnumerator,因此我对如何使用它们感到困惑。
感谢Barry,谢谢您的回答。
自从我问了这个问题后,我对Generics的投资就很有趣。我想开始在我的代码中实现它们。 “排序”问题有些令人困惑,因为似乎泛型似乎具有内置的处理排序的方法,但是没有很好的例子或文档来说明如何进行排序。
最后,我按照Barry的建议做了,并在Dictionary中建立了一个外部索引。但是,感觉仍然不对。
但是,那又让我感到惊讶:我试图用通用的TDictionary替换Gabr的GPStringHash。泛型使代码更加简洁。但最重要的是,TDictionary的速度是Gabr的3倍以上。对TryGetValue的1,704,667调用花费了0.45秒,但是对Gabr例程的相同操作花费了0.12秒。我不知道为什么,但是也许就像Gabr一样简单,它具有更快的哈希函数和存储桶组合。或许,泛型必须针对每种情况进行概括,从而固有地减慢了速度。
但是,也许Barry或其他Delphi开发人员应该注意这一点,因为3倍的加速最终可以使所有人受益。如果可以选择的话,我个人会比第三方软件包(甚至比Gabr的软件包更好)更快地使用语言内置的内容。但是现在,我将坚持使用GPStringHash。
最佳答案
就我而言,我使用TDictionary .TKeyCollection类。
function compareKey(const L, R: String): Integer;
begin
Result := SysUtils.CompareText(L, R);
end;
function getReverseSortedKeyArray(dictionary: TDictionary<String, String): TArray<String>;
var
keyArray: TArray<String>;
keyCollection: TDictionary<String, String>.TKeyCollection;
begin
keyCollection:= TDictionary<String, String>.TKeyCollection.Create(dictionary);
try
keyArray:= keyCollection.ToArray;
TArray.Sort<String>(keyArray, TComparer<String>.Construct(compareKey));
finally
keyCollection.Free;
end;
Result := keyArray;
end;
使用示例:
var
key: String;
keyArray : TArray<String>;
begin
keyArray := getSortedKeyArray (dictionary);
for key in keyArray do
begin
// ...
end;
end;