如何使用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替换GabrGPStringHash。泛型使代码更加简洁。但最重要的是,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;

09-05 22:32