#ruby #hash
#ruby #хэш
Вопрос:
Новичок в Ruby. Добавил хэш в хэш, но не смог «добавить» больше ключей и значений к хэшу, не записав первый ключ и значение в новый хэш. Пример кода:
contacts = {
"Jason" => {
"phone" => 833,
"twitter" => "sliceyboi",
"email" => "crystal@lake"
},
"Freddy" => {
"phone" => 666,
"tiktok" => "asdf",
"instagram" => "def",
"email" => "in.your@dreams"
}
}
while true
puts contacts
new_key_and_value = {}
puts "add name"
name_key = gets.chomp
puts "add media:"
new_key = gets.chomp
puts "add #{new_key} info:"
new_value = gets.chomp
new_key_and_value[new_key] = new_value
contacts[name_key] = new_key_and_value
end
Я могу добавить «Чаки» «электронная почта: кукла @ игрушки». Но если я пройдусь еще раз, для любого из имен для Чаки или любого из них, я надеялся добавить больше медиафайлов, а не перезаписать. Я знаю, что это как-то связано с созданным новым хэшем.
Так, например, что он делает:
add name
>Chucky
add media:
>email
add email info:
> doll@toys
{"Jason"=>
{ "phone"=>833,
"twitter"=>"sliceyboi",
"email"=>"crystal@lake"},
"Freddy"=>
{"phone" => 666,
"tiktok" => "asdf",
"instagram" => "def",
"email" => "in.your@dreams"},
"Chucky"=>
{"email"=>"doll@toys"}
}
add name
>Chucky
add media:
>tiktok
add tiktok info:
>chplay
{"Jason"=>
{ "phone"=>833,
"twitter"=>"sliceyboi",
"email"=>"crystal@lake"},
"Freddy"=>
{"phone" => 666,
"tiktok" => "asdf",
"instagram" => "def",
"email" => "in.your@dreams"},
"Chucky"=>
{"tiktok"=>"chplay"}
}
ищете:
{"Jason"=>
{ "phone"=>833,
"twitter"=>"sliceyboi",
"email"=>"crystal@lake"},
"Freddy"=>
{"phone" => 666,
"tiktok" => "asdf",
"instagram" => "def",
"email" => "in.your@dreams"},
"Chucky"=>
{"email"=>"doll@toys",
"tiktok"=>"chplay",
}
}
Так что это добавление в конец хэша Чаки
Комментарии:
1. Я предлагаю, чтобы всякий раз, когда вы приводите пример, вы показывали ожидаемый результат (как объект Ruby). Это, как правило, полезно для читателей.
Ответ №1:
Я знаю, что это как-то связано с созданным новым хэшем.
Вы правы. Все, что вам нужно сделать, это удалить new_key_and_value = {}
и вместо того, где вы пишете
new_key_and_value[new_key] = new_value
contacts[name_key] = new_key_and_value
напишите
# if contact doesn't exist create it.
if not contacts.key?(name_key) then contacts[name_key] = {} end
contacts[name_key][new_key] = new_value
В качестве альтернативы вы могли бы заменить new_key_and_value = {}
на new_key_and_value = contacts.key?(name_key) ? contacts[name_key] : {}
, но если этот контакт большой, вы создаете копию в памяти без причины, и это менее наглядно.
Ответ №2:
Вы могли бы использовать следующие методы.
def add_contact(contacts)
name = seek("What is name to add?")
h = {}
loop do
key, val = add_media
break if key == ''
h[key] = val
end
contacts[name] = h
contacts
end
def add_media
key = seek("Add media (enter empty string when finished")
return key if key.empty?
[key, seek("Add #{key} information")]
end
def seek(msg)
print "#{msg}: "
gets.chomp
end
Если диалог был:
add_contact contacts
What is name to add?: Chucky
Add media (enter empty string when finished: email
Add email information: doll@toys
Add media (enter empty string when finished: tiktok
Add tiktok information: chplay
Add media (enter empty string when finished:
метод вернет:
#=> { "Jason"=>{
# "phone"=>833,
# "twitter"=>"sliceyboi",
# "email"=>"crystal@lake"
# },
# "Freddy"=>{
# "phone"=>666,
# "tiktok"=>"asdf",
# "instagram"=>"def",
# "email"=>"in.your@dreams"
# },
# "Chucky"=>{
# "email"=>"doll@toys",
# "tiktok"=>"chplay"
# }
# }
Последняя строка add_contact
является необязательной. contacts
будет изменен по желанию, если он отсутствует. Я включил его, чтобы можно было написать что-то вроде
add_contact(contacts).each { |k,v| .... }
вместо
add_contact(contacts)
contacts.each { |k,v| .... }
если это необходимо.