Chapel 有动态数据结构吗?
Does Chapel have dynamic data structures?
Chapel 似乎专注于 n 维数组和固定大小的元组。乍一看,似乎没有动态数据结构。
一个特殊问题是您似乎必须预先声明关联数组的大小。其他语言的地图和词典不受此限制。
Chapel 是否有更动态的 map/dictionary 类型,我只是错过了它?
首先,你的问题的答案是肯定的。 map/dictionary 的内置等价物是 Chapel 中的关联数组。参见 associative arrays primer。
例如,让我们声明一个从名人名字到出生年份的字典。
首先,创建一个包含名称的域(即索引集):
var setOfNames : domain(string); // a domain (set) whose indices are strings
domain(t) 的类型声明,其中 t 是某种类型,创建关联域。
然后,在该域上创建一个存储整数年龄的数组。这实际上从 string -> int.
创建了一个映射
var nameToBirthYear : [setOfNames] int;
要将某人添加到集合中,我们需要先将他们添加到域中,然后在数组中设置他们的出生年份。
setOfNames.add("Thomas Jefferson");
nameToBirthYear["Thomas Jefferson"] = 1743;
setOfNames.add("Alan Turing");
nameToBirthYear["Alan Turing"] = 1912;
Chapel 旨在支持同一域上的多个阵列。所以如果我们想分别知道出生地,我们可以创建一个单独的数组来跟踪它。
var nameToBirthPlace : [setOfNames] string;
nameToBirthPlace["Thomas Jefferson"] = "the Colony of Virginia";
nameToBirthPlace["Alan Turing"] = "London, England";
现在,如果我们想添加一个新的名人怎么办?
setOfNames.add("Ada Lovelace");
// note now that both nameToBirthYear and nameToBirthPlace now have
// a value for the key "Ada Lovelace". That new element starts out with
// the default value - so it's 0 and the empty string in this case.
nameToBirthYear["Ada Lovelace"] = 1815;
nameToBirthPlace["Ada Lovelace"] = "London, England";
作为演示,我们将遍历索引集并打印出相关的数组元素。 (请注意,此循环对于压缩迭代更有意义,但我试图让此示例专注于关联数组和域)。
for name in setOfNames {
var birthYear = nameToBirthYear[name];
var birthPlace = nameToBirthPlace[name];
writeln(name, " started out in ", birthPlace, " in the year ", birthYear);
}
请注意,这些关联数组和域目前是使用哈希表实现的。可以创建自定义关联数组实现或为红黑树或任何需要的内容创建自定义(非数组)数据结构。
将来,可能有一天可以将键值对直接添加到关联数组(无需明确提及数组的域)。当其他数组不共享域时,一维数组支持此类功能 - 请参阅 array vector operations primer)。
Chapel 似乎专注于 n 维数组和固定大小的元组。乍一看,似乎没有动态数据结构。
一个特殊问题是您似乎必须预先声明关联数组的大小。其他语言的地图和词典不受此限制。
Chapel 是否有更动态的 map/dictionary 类型,我只是错过了它?
首先,你的问题的答案是肯定的。 map/dictionary 的内置等价物是 Chapel 中的关联数组。参见 associative arrays primer。
例如,让我们声明一个从名人名字到出生年份的字典。
首先,创建一个包含名称的域(即索引集):
var setOfNames : domain(string); // a domain (set) whose indices are strings
domain(t) 的类型声明,其中 t 是某种类型,创建关联域。
然后,在该域上创建一个存储整数年龄的数组。这实际上从 string -> int.
创建了一个映射var nameToBirthYear : [setOfNames] int;
要将某人添加到集合中,我们需要先将他们添加到域中,然后在数组中设置他们的出生年份。
setOfNames.add("Thomas Jefferson");
nameToBirthYear["Thomas Jefferson"] = 1743;
setOfNames.add("Alan Turing");
nameToBirthYear["Alan Turing"] = 1912;
Chapel 旨在支持同一域上的多个阵列。所以如果我们想分别知道出生地,我们可以创建一个单独的数组来跟踪它。
var nameToBirthPlace : [setOfNames] string;
nameToBirthPlace["Thomas Jefferson"] = "the Colony of Virginia";
nameToBirthPlace["Alan Turing"] = "London, England";
现在,如果我们想添加一个新的名人怎么办?
setOfNames.add("Ada Lovelace");
// note now that both nameToBirthYear and nameToBirthPlace now have
// a value for the key "Ada Lovelace". That new element starts out with
// the default value - so it's 0 and the empty string in this case.
nameToBirthYear["Ada Lovelace"] = 1815;
nameToBirthPlace["Ada Lovelace"] = "London, England";
作为演示,我们将遍历索引集并打印出相关的数组元素。 (请注意,此循环对于压缩迭代更有意义,但我试图让此示例专注于关联数组和域)。
for name in setOfNames {
var birthYear = nameToBirthYear[name];
var birthPlace = nameToBirthPlace[name];
writeln(name, " started out in ", birthPlace, " in the year ", birthYear);
}
请注意,这些关联数组和域目前是使用哈希表实现的。可以创建自定义关联数组实现或为红黑树或任何需要的内容创建自定义(非数组)数据结构。
将来,可能有一天可以将键值对直接添加到关联数组(无需明确提及数组的域)。当其他数组不共享域时,一维数组支持此类功能 - 请参阅 array vector operations primer)。