Як додати до наявного хешу в Ruby


102

Щодо додавання key => valueпари до наявного заселеного хешу в Ruby, я зараз працюю над Apress 'Beginning Ruby, і я щойно закінчив хеш-главу.

Я намагаюся знайти найпростіший спосіб досягти тих же результатів з хешами, як це робиться з масивами:

x = [1, 2, 3, 4]
x << 5
p x

Відповіді:


189

Якщо у вас є хеш, ви можете додати до нього елементи, посилаючись на них за ключем:

hash = { }
hash[:a] = 'a'
hash[:a]
# => 'a'

Тут, як [ ]створює порожній масив, { }буде створено порожній хеш.

Масиви мають нульовий або більше елементів у певному порядку, де елементи можуть бути дубльовані. У хешах є нуль або більше елементів, організованих за ключем , де ключі можуть не дублюватися, але значення, збережені в цих позиціях, можуть бути.

Хеші в Ruby дуже гнучкі і можуть мати ключі практично будь-якого типу, на які ви можете кинути. Це відрізняє від словникових структур, які ви знайдете в інших мовах.

Важливо пам’ятати, що специфічний характер ключа хеша часто має значення:

hash = { :a => 'a' }

# Fetch with Symbol :a finds the right value
hash[:a]
# => 'a'

# Fetch with the String 'a' finds nothing
hash['a']
# => nil

# Assignment with the key :b adds a new entry
hash[:b] = 'Bee'

# This is then available immediately
hash[:b]
# => "Bee"

# The hash now contains both keys
hash
# => { :a => 'a', :b => 'Bee' }

Ruby on Rails дещо плутає це, надаючи HashWithIndifferentAccess, де він буде вільно конвертувати між Symbol і String методами адреси.

Ви також можете індексувати майже все, включаючи класи, числа чи інші хеші.

hash = { Object => true, Hash => false }

hash[Object]
# => true

hash[Hash]
# => false

hash[Array]
# => nil

Хеші можуть бути перетворені в масиви і навпаки:

# Like many things, Hash supports .to_a
{ :a => 'a' }.to_a
# => [[:a, "a"]]

# Hash also has a handy Hash[] method to create new hashes from arrays
Hash[[[:a, "a"]]]
# => {:a=>"a"} 

Що стосується "вставлення" речей у хеш, ви можете робити це поодинці або використовувати mergeметод для комбінування хешей:

{ :a => 'a' }.merge(:b => 'b')
# {:a=>'a',:b=>'b'}

Зауважте, що це не змінює оригінальний хеш, а натомість повертає новий. Якщо ви хочете об'єднати один хеш в інший, ви можете скористатися merge!методом:

hash = { :a => 'a' }

# Returns the result of hash combined with a new hash, but does not alter
# the original hash.
hash.merge(:b => 'b')
# => {:a=>'a',:b=>'b'}

# Nothing has been altered in the original
hash
# => {:a=>'a'}

# Combine the two hashes and store the result in the original
hash.merge!(:b => 'b')
# => {:a=>'a',:b=>'b'}

# Hash has now been altered
hash
# => {:a=>'a',:b=>'b'}

Як і багато методів на String і Array, !вказує, що це операція на місці .


12
Багато цінної інформації, але не вистачає найосновнішої рецептури, на яку так просто відповів @robbrit.
дан

1
Будь ласка, відредагуйте свою відповідь, щоб насправді відповісти на поставлене запитання, бажано десь біля верху. Було б грубим, щоб я зробив це за вас.
Стефан

@Stephan Додав більш стислий приклад вгорі.
тадман



8
x = {:ca => "Canada", :us => "United States"}
x[:de] = "Germany"
p x

Я намагався реалізувати це з наступним: x['key'] = "value"однак я отримую помилки. Слід зазначити, що я працюю зі струнами.
Том

1
У чому помилка? Це може бути що завгодно, якщо ви більш конкретні.
тадман

1
hash = { a: 'a', b: 'b' }
 => {:a=>"a", :b=>"b"}
hash.merge({ c: 'c', d: 'd' })
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 

Повертає об'єднане значення.

hash
 => {:a=>"a", :b=>"b"} 

Але не змінює об'єкт, що викликає викликає

hash = hash.merge({ c: 'c', d: 'd' })
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 
hash
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 

Перепризначення робить трюк.


0
hash {}
hash[:a] = 'a'
hash[:b] = 'b'
hash = {:a => 'a' , :b = > b}

Ви можете отримати свій ключ і значення з введення користувача, тому ви можете використовувати Ruby .to_sym може перетворити рядок у символ, а .to_i перетворить рядок у ціле число.
Наприклад:

movies ={}
movie = gets.chomp
rating = gets.chomp
movies[movie.to_sym] = rating.to_int
# movie will convert to a symbol as a key in our hash, and 
# rating will be an integer as a value.

0

Ви можете використовувати оператор подвійної бризки, який доступний з Ruby 2.0:

h = { a: 1, b: 2 }
h = { **h, c: 3 }
p h
# => {:a=>1, :b=>2, :c=>3}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.