示例代码:
import std.stdio;
void main() {
auto a = ["one":1, "two":2, "three":3];
writeln(a);
}
但输出:
["three":3, "one":1, "two":2]
默认情况下,D优化存储密钥。如何禁用或重新实现它?
答案 0 :(得分:1)
那么,你是抱怨打印出来的订单与插入订单不符?关联数组是哈希表。没有秩序。 C ++ 11中的等效类型称为unordered_map
,特别是因为哈希表没有顺序。如何在表中放置键/值对完全基于键的哈希值。如果表被重新定义,它们在表中的顺序甚至可以完全改变。为了使哈希表保留用于打印或任何其他目的的插入顺序,它必须按插入顺序维护单独的密钥列表,这将是额外的开销,大多数人不需要,因此它不会有意义的是将其纳入核心AA实施中。
因此,如果您想维护插入顺序,您将不得不在一个单独的数据结构中自行维护 - 例如保留一个已插入哈希表的所有键的数组,当您将其添加到AA时,将该键附加到数组,并在从AA中删除该键时将其从数组中删除。
以下是按特定顺序打印AA的键/值对的一种可能实现:
import std.stdio;
auto orderKeys(int[string] hashTable, string[] keys)
{
import std.array;
static struct Range
{
@property bool empty() @safe const pure nothrow { return _keys.empty; }
@property auto front() @trusted const pure
{
static struct PrettyPrintTuple
{
string toString() @trusted pure
{
import std.string;
return format(`"%s":%s`, key, value);
}
string key;
int value;
}
return PrettyPrintTuple(_keys.front, _hashTable[_keys.front]);
}
void popFront() @safe pure nothrow
{
_keys.popFront();
}
int[string] _hashTable;
string[] _keys;
}
return Range(hashTable, keys);
}
void main()
{
auto a = ["one":1, "two":2, "three":3];
writeln(orderKeys(a, ["one", "two", "three"]));
}
不是单独维护一个AA和一个数组,而是拥有一个包含AA和数组的包装类型会更清晰,你可以在其上调用函数来添加,删除或访问元素,从而管理数组,以便它与插入顺序中AA当前的键完全匹配(而上面的范围假定所有键都在AA中),但我会把这个练习留给你。
答案 1 :(得分:0)
D关联数组不保留插入顺序。 您可以在此处找到更多信息(和实施):
http://forum.dlang.org/thread/dfyowpjhdaemhxhepfmk@forum.dlang.org?page=3
顺便说一句。我有一些更好的OrderedAA实现,所以如果你希望我可以公开它(如果我发现它:))