Delphi 5是否有一个排序的字典容器?

时间:2011-08-12 13:34:35

标签: delphi delphi-5

我是Delphi 5的新手并且正在寻找一个容器(理想情况下是一个内置的容器),它将完成与map在C ++中所做的相同的工作(即排序字典)。我已经进行了初步的谷歌搜索,但似乎没有任何明显的暗示。请有人能指出我正确的方向吗?

4 个答案:

答案 0 :(得分:3)

查看我们的TDynArray包装器。

它是任何现有动态数组(包括动态记录数组)的包装器,它将向动态数组添加类似TList的方法。具有更多功能,如搜索,排序,散列和二进制序列化。您可以使用外部Count变量设置阵列容量,以便插入速度更快。

type
   TGroup: array of integer;
var
   Group: TGroup;
   GroupA: TDynArray;
   i, v: integer;
   Test: RawByteString;
begin
  GroupA.Init(TypeInfo(TGroup),Group); // associate GroupA with Group
  for i := 0 to 1000 do begin
    v := i+1000; // need argument passed as a const variable
    GroupA.Add(v);
  end;
  v := 1500;
  if GroupA.IndexOf(v)<0 then // search by content
    ShowMessage('Error: 1500 not found!');
  for i := GroupA.Count-1 downto 0 do
    if i and 3=0 then
      GroupA.Delete(i); // delete integer at index i
  Test := GroupA.SaveTo; // serialization into Test
  GroupA.Clear;
  GroupA.LoadFrom(Test);
  GroupA.Compare := SortDynArrayInteger;
  GroupA.Sort; // will sort the dynamic array according to the Compare function
  for i := 1 to GroupA.Count-1 do
    if Group[i]<Group[i-1] then
      ShowMessage('Error: unsorted!');
  v := 1500;
  if GroupA.Find(v)<0 then // fast binary search
    ShowMessage('Error: 1500 not found!');

此示例使用整数数组,但您可以将它与记录数组一起使用,甚至包含字符串,嵌套动态数组或其他记录。

从Delphi 5到XE。

我发现它比泛型更容易使用(例如,用于自动序列化功能)。 ;)

请参阅http://blog.synopse.info/post/2011/03/12/TDynArray-and-Record-compare/load/save-using-fast-RTTI

答案 1 :(得分:1)

如果D5不包含THashedStringList那么也许这个(来自OmniThreadLibrary)可以完成这项任务:

https://github.com/gabr42/OmniThreadLibrary/blob/master/src/GpStringHash.pas

我引用:

  

使用Delphi 2007进行测试。也应该使用旧版本。

嗯,你的版本肯定更老了:)

答案 2 :(得分:1)

这可以使用TList.Sort或TObjectList.Sort在D5中“开箱即用”完成 - 在您的情况下,您可能希望按照以下方式实现类:

  TMyClass
   public  
      Index:integer;
      Value:TWhatever;
      ...
   end;

要存储在列表中,请使用索引值实现TList.Sort或TObjectList.Sort进行排序。这需要一些工作,但并不可怕。有关实现的详细信息,请参阅这些类的D5帮助。

不幸的是D5中没有泛型,所以你可能不得不进行大量的类型转换或为不同类型开发冗余容器类。

答案 3 :(得分:0)

这带回了回忆。还有另一种有趣的技术适合像您这样的古老版本的Delphi。请继续阅读!

从您的描述中,您听起来像是想要一个相当通用的容器 - 也就是说,您可以使用各种类型的容器。这是对于泛型的渴望(是的,使用一个新的Delphi!)但是在过去,曾经有一种轻微的hacky方式来使用Delphi 2009之前的实现模板/泛型,使用一系列defineinclude的。{它花了一些谷歌搜索,但这里an article on these 'generics'就像我记得的那样。它是从2001年开始的;在那些日子里,Delphi 5仍然是最新的。

粗略的想法是这样的:写一个类来做你想要的(这里,从键到值的映射)类型,并让它工作。然后更改该文件以使用类型的特定名称(TMyType,真正的任何东西)并删除文件,使其不再是有效单位,但仅包含代码。 (我认为实际上有两个部分文件:一个用于interface部分,一个用于implementation。)使用{$include ...}包含文件内容,因此您的整个Pascal文件都是使用您的文件编译的定义,然后是使用这些定义的其他部分包含文件的内容。整洁,hacky,丑陋?我不知道,但它有效:)

示例文章创建了一个类型化的对象列表(即不是TObjectTMemoTButton等的列表。)最终得到的文件看起来像这样(从链接文章中复制):

unit u_MemoList;

interface

uses
  Sysutils,
  Classes,
  Contnrs,
  StdCtrls;

{$define TYPED_OBJECT_LIST_TEMPLATE}
type
  _TYPED_OBJECT_LIST_ITEM_ = TMemo;
{$INCLUDE 't_TypedObjectList.tpl'}

type
  TMemoList = class(_TYPED_OBJECT_LIST_)
  end;

implementation

{$INCLUDE 't_TypedObjectList.tpl'}

end.

您需要编写自己的类似地图的类,尽管您应该能够将它基于此类。我记得曾经有一组漂浮在网络上的“通用”容器,可能使用了这种技术,我猜测地图就在其中。我担心我不知道它在哪里或它是谁,谷歌搜索这种东西显示现代版本的德尔福有很多结果。写你自己可能是最好的。

修改:我找到了相同的文章(相同的文字和内容),但better formatted on the Embarcadero Developer Network site

祝你好运!