具有连续编号键的哈希与数组有何不同?

时间:2015-03-12 13:27:44

标签: ruby

考虑:

foo = {
    0 =>    "a",
    1 =>    "b",
    2 =>    "c"
}

bar = ["a","b","c"]

从功能上讲,这些对我来说似乎是一样的。区别在于它们是不同的数据类型,即使数据本身实际上是相同的吗?

我觉得数组应该是哈希的子类,不同之处在于隐含了键,因此不需要由程序员明确设置。

3 个答案:

答案 0 :(得分:3)

语义和实现都存在差异。

从语义上讲,数组是有序值的列表。从列表中删除项目会移动列表中的所有其他项目。列表中有一个头部和尾部,您可以在特定位置插入。列表中可能存在间隙(在给定索引处没有存储值)。

相比之下,哈希不一定有任何明确的排序(虽然他们在Ruby 1.9+中做过),没有头或尾,在迭代中不会有间隙,并且不允许在可迭代顺序的中间插入(至少不使用整个哈希)。

实施方面,他们是白天和黑夜。数组是非常简单的数据结构 - 在引擎盖下,它们只是一个连续的内存块,它由(索引*结构大小)索引。获取/设置都是O(1)。另一方面,哈希往往是链表的列表。您通过散列函数传递一个键,以确定您的集合中的哪个链接列表要存储或检索该值,然后迭代链接列表以检索该值。插入是O(1),检索是O(n log n)。

虽然PHP背景可能使得Arrays看起来应该是Hash的子类,因为PHP将它们混为一谈,但它们是具有不同目的和行为的非常不同的数据结构,并且应该保持独立。

答案 1 :(得分:2)

你的同化不会扩展到一些自然定义的概念。

例如,添加+自然是在数组上定义的:

["a", "b", "c"] + ["d", "e", "f"]
# => ["a", "b", "c", "d", "e", "f"]

如果您遵循同化并使用哈希对应merge执行类似操作,则会得到不同的结果:

{0 => "a", 1 => "b", 2 => "c"}.merge({0 => "d", 1 => "e", 2 => "f"}
# => {0 => "d", 1 => "e", 2 => "f"}

编辑我认为这种差异的基础是从0开始的连续编号索引对于数组是自动的。无论你对数组做什么,总是满足条件。为了保持同化,你必须为“哈希的数组部分”添加一个机制来执行此操作。

答案 2 :(得分:-3)

数组将更有效地解析数据,因为MRI(Matz的Ruby解释器 - ruby​​解释器)必须将散列中的键评估为字符串/符号而不是整数索引值。