泛型字典类是否有通过索引获取键的方法?

时间:2017-11-30 11:17:50

标签: delphi dictionary

这可能是一个非常简单的问题,但我认为我是心理上的盲人或其他东西;如何通过Delphi(10.1)中的Dictionary类中的索引获取密钥。我的意思是结构有一个名为Count的属性,所以它必须有一个类型的数组或列表,为什么我不能通过索引得到键。

我也在Dictionary类中尝试过KeyCollection属性,但它也没有任何用处。我需要这样的东西:

key: string;
key := dicTest.GetKey(keyIndex);

非常感谢。

3 个答案:

答案 0 :(得分:7)

Delphi RTL通用字典是无序的。由于无序,容器中的项目不具有有意义的索引。

可以使用Keys属性枚举密钥:

var
  dict: TDictionary<string, Integer>;
  key: string;
....
for key in dict.Keys do
  Writeln(key);

同样,可以使用Values属性枚举值。

var
  dict: TDictionary<string, Integer>;
  value: Integer;
....
for value in dict.Values do
  Writeln(value);

如果你想枚举键/值对,那么字典本身就为它提供了一个枚举器:

var
  dict: TDictionary<string, Integer>;
  item: TPair<string, Integer>;
....
for item in dict do
  Writeln(item.Key, ', ', item.Value);

请注意,对于这些枚举器中的每一个,都不保证项目的顺序。简单的行为,如在字典中添加新项,可能会导致枚举项的顺序发生变化。

答案 1 :(得分:4)

要添加David的答案,字典或散列表结构的重点是在内存中非常有效地存储和检索键值对。

这是通过以下方式实现的:

  • 根据密钥将项目放入大型内存块中的可预测位置。
  • 在尝试查找该项目时,您知道应该存储的位置( 基于密钥 ),并且可以立即转到希望找到它的那个位置。

下图说明了:

        +-------------+
        |  ..         |
        |  ..         |
Add     |World (Data) |   Find
Hello   |Abc   (Data) |   Hello
  |     |  ..         |     |
  |     |  ..         |     |
  +---> |Hello (Data) | <---+
        |  ..         |
        |  ..         |
        |Xyz   (Data) |
        +-------------+

请注意以下事项:

  • 没有订购项目的插入位置。
  • 基本操作需要知道要查找的密钥。
  • 虽然Delphi允许对项目进行迭代,但不保证其位置一致。
  • 这种结构的一大优点是,无论收集的大小有多大,添加,查找和删除项目都具有相同的性能。这被称为具有复杂度的顺序 O(1)。
  • 这些结构在内存要求方面往往效率低下。您可能已经注意到上图中分配的内存中的“间隙”。
  • 没有用于了解集合中项目数量的内置机制,但是在单个额外字段中添加/删除项目时,可以轻松跟踪数字。 (这是Delphi的实现所做的。)了解计数并不意味着您可以按索引访问项目。

总结

如果您无法跟踪密钥,则Dictionary不适合您。使用Listarray可能会更好。虽然我建议您努力了解这些结构的优点和局限性,以帮助确定哪种最适合工作的工具

答案 2 :(得分:3)

通过索引访问密钥的最简单方法是将它们作为数组检索。 Keys属性为其提供了一个函数:ToArray