У меня проблема с Ruby Monk, https://rubymonk.com/learning/books/1-ruby-primer/problems/155-restaurant#solution4804
Их решение великолепно; Мне нравится, компактнее моего. Проблема у меня, я просто не понимаю, почему это работает только тогда, когда я удаляю оператор splat из параметра стоимости orders
. Даже если мне не следует поступать таким образом, я изо всех сил пытаюсь понять, в чем дело. Я знаю, иногда нет необходимости во всем разбираться, и лучше просто двигаться дальше... но любопытно.
Вот мой:
class Restaurant
def initialize(menu)
@menu = menu
end
def cost(*orders)
total_cost = 0
orders.each do |item, number|
total_cost += @menu[item] * number
end
end
menu = {:rice => 3, :noodles => 2}
orders = {:rice => 1, :noodles => 1}
eat = Restaurant.new(menu)
puts eat.cost(orders)
Изменить: включить предлагаемое ими решение ниже
class Restaurant
def initialize(menu)
@menu = menu
end
def cost(*orders)
orders.inject(0) do |total_cost, order|
total_cost + order.keys.inject(0) {|cost, key| cost + @menu[key]*order[key] }
end
end
end
Изменить: чтобы прояснить и ответить на мой собственный вопрос в комментарии
Я попробовал эти эксперименты, и они показывают, что inject
«удаляются» скобки массива, которые «надеваются» на знак. Возможно, это не самый правильный способ думать об этом? Это помогает прояснить мое замешательство.
order = { :rice => 1, :noodles => 1 }
menu = { :rice => 3, :noodles => 2 }
[order].inject(0) do |bla, blu|
p bla #=> 0
p blu #=> {:rice=>1, :noodles=>1}
p blu.keys #=> [:rice, :noodles]
end
Enumerable#inject
: он повторяет над элементами в коллекции, по одному за раз. Таким образом, на каждой итерации у вас нет массива, у вас есть только элемент из массива. Он удаляет массив так же, какeach
, обрабатывая содержимое по одному элементу за раз. - person Phrogz   schedule 13.02.2014