2013-09-27 3 views
7

У меня есть один хэш, где ключ - это строка, а значение - массив строки. я хочу что-то вроде этого:Хэш массивов в Ruby

{"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 '[]' для nil: NilClass ' hash1.sort_by {| k, v | v [0]} '#undefined method '[]' для nil: NilClass – Aparichith

+0

Я не совсем понимаю ваш вопрос. Пожалуйста, оставьте еще один комментарий с примером 'hash1' и то, что вы хотите получить в результате хэша. –

+0

рассмотрим массив хешей, подобный этому: '[{" a "=> [576, 236]}, {" z "=> [348, 4859]}, {" b "=> [174, 98] }, {"t" => [165, 145]}, {"u" => [97, 184]}, {"m" => [595, 374]}, {"g" = > [61, 86]}] ' Как я могу отсортировать массив хэшей, используя сумму значений для каждой клавиши? как это '[{ "г"=> [348, 4859]}, { "а"=> [576, 236]}, { "м"=> [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' и снова проверьте идентификатор, это то же самое (все еще эта же ссылка), когда вы 'arr = []' вы создаете новый объект с тем же именем, переопределяя старый, проверяете его с помощью 'arr.object_id', и у вас будет другой номер идентификатора, что означает, что новый объект :) – Gerep

Смежные вопросы