首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Delphi2009中按字母顺序列出TDictionary?

如何在Delphi2009中按字母顺序列出TDictionary?
EN

Stack Overflow用户
提问于 2010-03-27 05:36:06
回答 3查看 17.3K关注 0票数 19

如何使用TEnumerator按键的顺序遍历TDictionary?

我有这样的东西:

代码语言:javascript
运行
复制
  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,所以我不知道这些代码是如何设计来使用的。

谢谢巴里你的回答。

自从我提出这个问题以来,我就开始尝试泛化,这是很有趣的。我想开始在我的代码中实现它们。“排序”问题有点令人费解,因为看起来Generics似乎有处理排序的方法,但是对于如何进行排序却没有很好的示例或文档。

最后,我按照巴里的建议,在字典中建立了一个外部索引。尽管如此,感觉还是不太对劲。

然而,后来我有了另一个惊喜:我试图用泛型的加布尔's TDictionary替换GPStringHash。代码在泛型中略显简洁。但底线是TDictionary比Gabr的慢3倍多。对TryGetValue的1704 667次调用需要.45秒,但对TryGetValue例程的相同操作需要.12秒。我不知道为什么,但它可能就像Gabr具有更快的Hash函数和桶形组合一样简单。或者,可能泛型必须针对每一种情况进行泛化,这从本质上减缓了它的速度。

也许Barry或其他Delphi开发人员应该考虑这一点,因为3倍的加速可能最终对每个人都有好处。如果有选择的话,我个人更愿意使用语言中内置的东西,而不是第三方包(即使是像Gabr那样好的包)。但就目前而言,我将坚持GPStringHash。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-11 07:23:46

在我的例子中,我使用了>.TKeyCollection类TDictionary < String。

代码语言:javascript
运行
复制
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;

使用实例:

代码语言:javascript
运行
复制
var
  key: String;
  keyArray : TArray<String>;
begin
    keyArray  := getSortedKeyArray (dictionary);
    for key in keyArray  do
    begin
      // ...
    end;
end;
票数 8
EN

Stack Overflow用户

发布于 2010-03-27 06:43:18

字典是一个哈希表,所以它不按排序顺序存储项。TEnumerator很简单--它只是迭代项的一种方法。

要获得订单中的项目,您需要对它们进行排序。一种方法是将它们放入列表并对列表进行排序,如下所示:

代码语言:javascript
运行
复制
var
  list: TList<string>;
begin
  list := TList<string>.Create(Dic.Keys);
  try
    list.Sort;
    // process sorted list of items now
  finally
    list.Free;
  end;
end;
票数 21
EN

Stack Overflow用户

发布于 2013-04-18 09:42:22

下面是通过Array<T>TList<T>进行排序的示例代码。它保留了键值对关系,也可以根据值而不是键对进行排序。此外,它使用匿名方法进行排序。

确保在您的Generics.Collections子句中包括Generics.Defaultsuses。使用TArray<T>进行排序的第一个方法

代码语言:javascript
运行
复制
procedure TestSortDictionaryViaArray;
var
  D: TDictionary<string, Integer>;
  A: TArray<TPair<string, Integer>>;
  P: TPair<string, Integer>;
begin
  D := TDictionary<string, Integer>.Create;

  D.Add('Test - 6', 6);
  D.Add('Test - 1', 1);
  D.Add('Test - 0', 0);
  D.Add('Test - 4', 4);
  D.Add('Test - 3', 3);
  D.Add('Test - 5', 0);
  D.Add('Test - 2', 2);

  A := D.ToArray;

  TArray.Sort<TPair<string, Integer>>(A,
    TComparer<TPair<string, Integer>>.Construct(
      function (const L, R: TPair<string, Integer>): Integer
      begin
        Result := CompareStr(L.Key, R.Key);
      end)
  );

  for P in A do
    ShowMessage(P.Key);
  D.Free;
end;

这是使用TList<T>

代码语言:javascript
运行
复制
procedure TestSortDictionaryViaList;
var
  D: TDictionary<string, Integer>;
  L: TList<TPair<string, Integer>>;
  P: TPair<string, Integer>;
begin
  D := TDictionary<string, Integer>.Create;

  D.Add('Test - 6', 6);
  D.Add('Test - 1', 1);
  D.Add('Test - 0', 0);
  D.Add('Test - 4', 4);
  D.Add('Test - 3', 3);
  D.Add('Test - 5', 0);
  D.Add('Test - 2', 2);

  L := TList<TPair<string, Integer>>.Create(D);

  L.Sort(
    TComparer<TPair<string, Integer>>.Construct(
      function (const L, R: TPair<string, Integer>): Integer
      begin
        Result := CompareStr(L.Key, R.Key);
      end)
  );

  for P in L do
    ShowMessage(P.Key);

  D.Free;
  L.Free;
end;

附加(和不必要的)信息:TList<T>方法需要释放列表,而TArray<T>不需要释放。在内部,TList<T>使用TArray<T> (例如,TArray有一个BinarySearch()类方法,TList<T>有一个BinarySearch方法)。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2528265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档