Как добавить к существующему хешу в Ruby


102

Что касается добавления key => value пары к существующему заполненному хешу в Ruby, я нахожусь в процессе работы с Apress 'Beginning Ruby и только что закончил главу о хешах.

Я пытаюсь найти самый простой способ достичь тех же результатов с хешами, что и с массивами:

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

Ответы:


190

Если у вас есть хэш, вы можете добавлять в него элементы, ссылаясь на них по ключу:

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.
danh

1
Пожалуйста, отредактируйте свой ответ, чтобы фактически ответить на заданный вопрос, желательно где-нибудь в верхней части. Было бы грубо с моей стороны сделать это за вас.
Стефан

@Stephan Добавил более лаконичный пример вверху.
tadman



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

Я пытался реализовать это следующим образом: x['key'] = "value"однако получаю ошибки. Следует упомянуть, что я работаю со строками.
Tom

1
Что за ошибка? Это может быть что угодно, если вы не укажете более конкретно.
tadman

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.