2013-09-27 361 views
7

我有一个散列,其中键是一个字符串,值是一个字符串的数组。 我想是这样的:红宝石数组哈希

{"k1"=>["v1", "v2"], "k2"=>["v3", "v4"]} 

我只有一个哈希和一个阵列来实现这一点。我已经编写这样的事情:

hash1 = Hash.new 
arr = Array.new 
arr.push "v1" 
arr.push "v2" 
hash1["k1"] = arr 

#hash is like this: {"k1"=>["v1", "v2"] 
#Now I clear the array to read the new values 

arr. clear 
arr.push "v3" 
arr.push "v4" 
hash1["k2"] = arr 
puts hash1 

#Output: {"k1"=>["v3", "v4"], "k2"=>["v3", "v4"]} 
#Notice that k1's value also got updated 

然后,我改变了一行:

hash1 = Hash.new 
arr = Array.new 
arr.push "v1" 
arr.push "v2" 
hash1["k1"] = arr 

arr = [] # ** This is the only changed line. Now k1's value is correct. ** 
arr.push "v3" 
arr.push "v4" 
hash1["k2"] = arr 
puts hash1 
#Output: {"k1"=>["v1", "v2"], "k2"=>["v3", "v4"]} (which I wanted) 

是否有人可以解释我这样做是如何发生的?我对Ruby很新。理想情况下,解决这个问题的正确方法是什么?

+2

“我只有一​​个散列和一个数组来执行此操作。不在你的第二个例子中。你有两个数组。 – Ajedi32

+2

'{}'几乎总是比'Hash.new'更好,'[]'更好''Array.new'。 – tadman

+0

@tadman为什么更好?这仅仅是为了可读性吗?还是还有其他好处? –

回答

8

这应该告诉你发生了什么(object_id是你的朋友)。 (我在Object_id中插入了一个下划线,以便更容易看出区别。)

hash1 = {}   # => {} 
arr = ["v1", "v2"] # => ["v1", "v2"] 
arr.object_id   # => 7016637_4343580 
hash1["k1"] = arr  # => ["v1", "v2"] 
hash1     # => {"k1"=>["v1", "v2"]} 
hash1["k1"].object_id # => 7016637_4343580 
arr.clear    # => [] 
arr.object_id   # => 7016637_4343580 
arr << "v3" << "v4" # => ["v3", "v4"] 
arr.object_id   # => 7016637_4343580 
hash1["k2"] = arr  # => ["v3", "v4"] 
hash1     # => {"k1"=>["v3", "v4"], "k2"=>["v3", "v4"]} 
hash1["k1"].object_id # => 7016637_4343580 
hash1["k2"].object_id # => 7016637_4166580 

arr = []    # => [] 
arr.object_id   # => 7016637_4036500 
arr = ["v5", "v6"] # => ["v5", "v6"] 
arr.object_id   # => 7016637_3989880 
hash1     # => {"k1"=>["v3", "v4"], "k2"=>["v3", "v4"]} 
hash1["k1"].object_id # => 7016637_4343580 
hash1["k2"] = arr  # => ["v5", "v6"] 
hash1     # => {"k1"=>["v3", "v4"], "k2"=>["v5", "v6"]} 
hash1["k1"].object_id # => 7016637_4343580 
hash1["k2"].object_id # => 7016637_3989880 
+0

很好的解释。 如果我想排序我的哈希价值v1或v2我该怎么办? 'hash1.sort_by {| k,v | v.first}'#undefined method'[]'为零:NilClass 'hash1.sort_by {| k,v | v [0]}'#undefined method'[]'为零:NilClass – Aparichith

+0

我不太明白你的问题。请用'hash1'的例子留下另一条评论,并且希望散列的结果是什么。 –

+0

考虑如下的哈希阵列 {[“a”=> [576,236]}, {“z”=> [348,4859]}, {“b”=> [174,98] }, {“t”=> [165,145]}, {“u”=> [97,184]}, {“m”=> [595,374] > [61,86]}]' 我应该如何使用每个键的值总和对我的散列数组进行排序? 这样 '[{ “Z”=> [348,4859]}, { “一个”=> [576,236]}, {的 “m”=> [595,374]}, {“t”=> [165,145]}, {“u”=> [97,184]}, {“b”=> [174,98]}, {“g”=> [61 ,86]}]' – Aparichith

3

您保存在散列表中的数组仍然以arr为参考,因此很清楚地使用arr.clear并使用arr.push会清除并向保存在散列表中的值添加新值。但是现在做arr = [],arr现在会引用一个新的数组,它与散列中保存的不同。

而且你可以简单地添加新的数组与哈希:

hash1["k2"] = ["v3", "v4"] 

或者

hash1["k2"] = %w[v3 v4] 
+2

添加到答案中,您可以看到它的工作原理,在您的'arr','arr.object_id'上执行此操作,您将收到一个数字,当您使用'clear'并再次检查id时,它是一样的同样的参考文献),当你arr = []'你创建一个同名的新对象时,覆盖旧的对象,用'arr.object_id'检查它,你将得到一个不同的id号,这意味着一个新的对象:) – Gerep