我正在研究一个rubymonk编码练习的解决方案,并且很难理解cost
方法中发生了什么。
作为参考,menu
是{:rice => 3, :noodles => 2}
,其目的是从menu
计算订单的总成本。
例如:
{:rice => 1, :noodles => 1} )
我提出的解决方案更简单,至少在我的头脑中是这样,但是返回了一个“无法将符号转换为整数”的错误,我无法通过
to_i
来纠正这个错误。 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
有人能简单地解释一下
cost
方法中的每一步吗? 最佳答案
考虑到atotal cost
正在计算中,似乎@menu
包含单价(通常情况下,最好的餐厅除外),并且每个订单都包含所订购的每个菜单项的数量假设:
@menu = {rice: 0.69, noodles: 0.89}
其中,值是单价,
orders
的元素如下所示:{rice: 3, noodles: 2}
其中值是订购的数量提供本订单所列数量的成本为:
(3)(0.69) + (2)(0.89) = 3.95
你要把这笔费用加在所有订单上。
首先,我们这样写方法,
def cost( *orders )
orders.inject(0) do |total_cost, order|
total_cost + order.keys.inject(0) do |cost, key|
cost + order[key] * @menu[key]
end
end
end
以澄清其结构
inject
(又名reduce
)正在对orders
进行迭代,并在变量total_cost
中累积一个值通过将参数传递给total_cost
,可以为inject
指定一个初始值(正如您所做的那样)。如果不给inject
一个参数初始值,total_cost
设置为等于inject
后面的块中的第一个计算值在这种情况下,如果将参数丢弃到inject
,则会得到相同的结果。对于
orders
(块变量order
)的第一个值,将以下数字添加到累加器中:order.keys.inject(0) do |cost, key|
cost + @menu[key] * order[key]
end
要获得这个值,ruby必须执行一个边计算。假设
total_cost
和@menu
具有我上面给出的值。order
以inject(0)
作为累加器在order.keys
上迭代(即[:rice, :noodles]
)。对cost
执行块,然后对:rice
执行块: cost + order[:rice] * @menu[:rice] => 0 + 3 * 0.69 # => 2.07 => cost
cost + order[:noodles] * @menu[:noodles] => 2.07 + 2 * 0.89 # => 3.95 => cost
这就完成了侧边计算,因此3.95被添加到外部累加器
noodles
(之前等于零)total_cost
的下一个元素然后由外部的orders
处理,依此类推。