考虑:
foo = {
0 => "a",
1 => "b",
2 => "c"
}
bar = ["a","b","c"]
从功能上讲,这些对我来说似乎是一样的。区别在于它们是不同的数据类型,即使数据本身实际上是相同的吗?
我觉得数组应该是哈希的子类,不同之处在于隐含了键,因此不需要由程序员明确设置。
答案 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解释器)必须将散列中的键评估为字符串/符号而不是整数索引值。