我正在研究一个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具有我上面给出的值。
orderinject(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处理,依此类推。

10-06 13:49
查看更多