以数组为键的哈希

时间:2013-12-07 11:17:01

标签: ruby hash

我正在定义一个散列,其中数组作为键,另一个数组作为其值。例如:

for_example = {[0,1] => [:a, :b, :c]}

一切都如下所示。

my_hash = Hash.new([])
an_array_as_key = [4,2]
my_hash[an_array_as_key]                #=> []
my_hash[an_array_as_key] << "the"       #=> ["the"]
my_hash[an_array_as_key] << "universal" #=> ["the", "universal"]
my_hash[an_array_as_key] << "answer"    #=> ["the", "universal", "answer"]

但是如果我尝试访问密钥:

my_hash                           #=> {}
my_hash.keys                      #=> []
my_hash.count                     #=> 0
my_hash.values                    #=> []
my_hash.fetch(an_array_as_key)    # KeyError: key not found: [4, 2]
my_hash.has_key?(an_array_as_key) #=> false

Rehash无济于事:

my_hash        #=> {}
my_hash.rehash #=> {}
my_hash.keys   #=> []

但保存了值:

my_hash[an_array_as_key] #=> ["the", "universal", "answer"]

我错过了什么吗?

1 个答案:

答案 0 :(得分:7)

要理解这一点,您需要了解Hash::newHash::new(ob)之间的区别。假设您使用hash或哈希文字Hash::new定义{}对象。现在,无论何时编写代码hsh[any_key],都会看到两种输出,如果any_key不存在,那么默认nil将会返回,否则将返回与密钥相关的任何值。如果您使用Hash创建任何Hash.new对象,则相同的解释将适用。

现在Hash.new(ob)Hash.new相同,但有一点不同,您可以为该哈希对象的不存在的键设置所需的任何默认值。

my_hash = Hash.new([])
my_hash[2] # => []
my_hash[2].object_id # => 83664630
my_hash[4] # => []
my_hash[4].object_id # => 83664630
my_hash[3] << 4 # => [4]
my_hash[3] # => [4]
my_hash[3].object_id # => 83664630
my_hash[5] << 8 # => [4, 8]
my_hash[5] # => [4, 8]
my_hash[5].object_id # => 83664630

现在请参阅上面的示例my_hash,其中没有234等密钥。但是object_id证明了,所有键访问都会导致返回相同的数组对象。 my_hash[2]未将密钥添加到哈希my_hash,而是在该密钥存在时尝试访问密钥2的值,否则返回默认值{{1} }。请记住,my_hashmy_hash[2]等所有行只不过是对Hash#[]方法的调用。

但是有一种第三种方式可能正在寻找,可能是my_hash[3]。使用此样式,如果该键没有,则可以向哈希对象添加键。存在, ,默认值为同一个类实例,但不是同一个实例。 ,而您正在进行实际的Hash#[]方法调用。

Hash::new {|hash, key| block }