#ruby #hash
#ruby #хэш
Вопрос:
Приношу свои извинения за потенциально глупый вопрос, я абсолютный новичок в Ruby и коде в целом.
Я настроил хэш с некоторыми предопределенными значениями. Я хочу запросить у пользователя ввод, если этот ввод соответствует существующему ключу, я хочу, чтобы соответствующее значение было обновлено (в данном случае 1). Затем я хочу распечатать все текущие актуальные значения.
hash = {"apple": 6, "banana": 2, "carrot": 3}
order = gets.chomp.downcase
hash.each do |key, value|
if key.to_s == order
value = 1
puts "Your order includes: #{value} #{key}."
end
end
Моя проблема в том, что я знаю, как напечатать только одну пару ключ-значение.
Например, если пользователь вводит «apple», я бы хотел, чтобы на выходе было написано: «Ваш заказ включает: 7 яблок, 2 банана, 3 моркови».
Комментарии:
1. Я думаю, вы хотели бы умножить «яблоко» на «яблоки», когда количество больше 1.
2. Помните, что вы можете искать вещи в хэше, вам не нужно прокручивать его и сравнивать.
if (value = hash[order])
делает все это одним выстрелом. Подход, который у вас здесь, постепенно замедляется по мере увеличения количества элементов. Метод поиска занимает примерно одинаковое количество времени независимо от количества записей.3. Суть проблемы здесь в том, что
value = 1
хэш не обновляется. Вам нужно использоватьHash#[]=
Ответ №1:
hash = {apple: 6, banana: 2, carrot: 3}
order = gets.chomp.downcase.to_sym
hash[order] = hash.fetch(order, 0) 1
puts "Your order includes: " hash.map { |k, v| "#{v} #{k}" }.join(", ")
Некоторые примечания:
-
ваша инициализация хэша
hash = {"apple": 6, "banana": 2, "carrot": 3}
. ключи вашего хэша выглядят строками, но если вы используете этот синтаксис с двоеточием, они становятся символами. Итак, у вас есть два варианта. этот синтаксис:hash = {"apple" => 6, "banana" => 2, "carrot" => 3}
или вы можете использовать символы, как я, и преобразовать пользовательский ввод в символ
-
что действительно здорово в hash, так это то, что вам не нужно перебирать элементы, чтобы найти то, что вы ищете. Существует сопоставление между ключами и значениями, поэтому легко найти и обновить значение
-
в третьей строке я имею дело с тем фактом, что ключ не может быть в хэше,
fetch
в этом случае у меня было 0. затем я увеличиваю и присваиваю обратно этому ключу
Ответ №2:
В вопросе не указано, хотите ли вы изменить начальный хэш, поэтому я полагаю, что вы это делаете. Тогда будет сделано следующее.
hash = Hash.new(0).merge(apple: 6, banana: 2, carrot: 3)
hash[gets.chomp.downcase.to_sym] = 1
puts "Your order includes: " <<
hash.map { |k, v| [v, k].join(' ') }.join(', ')
или:
puts hash.reduce("Your order includes: ") { |acc, (k, v)|
acc << "#{v} #{k}, "
}[0..-3]
Ответ №3:
Рассмотрите возможность инициализации хэша, предоставляющего значение по умолчанию (Hash#default)
basket = {'apple' => 6, 'banana' => 2, 'carrot' => 3}
basket.default = 0 # <-- set default 0 for start counting new keys
Определите метод представления данных:
def show(basket)
puts "Your order includes:"
basket.each{ |key, value| puts "#{value}: #{key}" }
end
Захват пользовательского ввода в цикле (объяснение в комментариях):
loop do
puts "Place your order:"
order = gets.downcase.chomp # <-- format the input
break if order == '0' # <-- breaks the input loop if this contition is matched
next unless basket.has_key? order # <-- skip to next loop no matches with hash keys or remove this line if you want to count also non initialised keys
basket[order] = 1 # <-- increment by one the key
show(basket) # <-- call the metod to show the basket
end
show(basket)