首页 > 解决方案 > 如何在哈希中舍入一个值?

问题描述

在举重的背景下,我正在尝试计算杠铃每侧所需的板数,给定要举起的总重量并假设杠铃重 45 磅。最小的盘子是 2.5 磅,我想四舍五入到每边所需的最接近的 2.5 磅盘子的数量。目前,给定 140 磅的总重量,结果如下所示:

{:"45"=>1, :"2.5"=>0.8}

如何仅将“2.5”板的值四舍五入到最接近的整数(0 或 1)?

def plates_for(lb)
lb = (lb - 45) / 2
  plate_values = {'45': 45, '25': 25,'10': 10, '5': 5, '2.5': 2.5}
  pairs = plate_values.map do |plate, weight|
    number_of_plates = lb / weight
    lb = lb % weight
    [plate, number_of_plates]
  end

  plates_needed = pairs.select { |plate, weight| weight > 0 }
  p plates_needed.to_h
end

plates_for(140)

标签: ruby

解决方案


原答案:

plates_needed[:'2.5'] = plates_needed[:'2.5'].round

默认情况下,这将四舍五入到最接近的整数,如果介于两者之间,则向上舍入。如果您希望使用不同的行为来四舍五入到最接近的一半,您可以指定一个可选关键字:

2.5.round(half: :up)      #=> 3 (DEFAULT)
2.5.round(half: :down)    #=> 2
2.5.round(half: :even)    #=> 2
3.5.round(half: :up)      #=> 4 (DEFAULT)
3.5.round(half: :down)    #=> 3
3.5.round(half: :even)    #=> 4

或者,如果你想 _always_round down 然后使用Integer#floor; 如果你想总是四舍五入,那么使用Integer#ceil.

完整解决方案:

def plates_for(lb)
  lb = (lb - 45).to_f / 2
  plate_values = [45, 25, 10, 5, 2.5]
  pairs = plate_values.map do |weight|
    number_of_plates = (lb / weight).round
    lb -= number_of_plates * weight
    [weight, number_of_plates]
  end.to_h

  pairs.select { |weight, number_of_plates| number_of_plates > 0 }
end

p plates_for(140) #=> {45=>1, 5=>1}

我已经更改了代码的几个细微部分。请注意,我的代码中的最终结果是不同的!我明白{45=>1, 5=>1}了,这是正确的。这些变化是:

  • 在第 2 行添加。如果没有这个,如果所需的总重量是偶数,则to_f您将四舍五入杆每侧的所需重量。0.5例如,(140 - 45) / 2 == 47,但是(140 - 45).to_f / 2 == 47.5
  • 定义plate_values为简单的Array,以避免混淆。无需将其初始化为Hash.
  • 添加Integer#round到板数计算。这可以防止在此处分配非整数值。如上所述,您可以在此处选择使用多种变体。
  • 由于(lb / weight).round可能一样lb % weight(即,如果我们四舍五入!),在这里使用这个值是错误的。始终减去我们实际添加到酒吧的重量。
  • 为简化起见,立即调用.to_h此映射的结果。
  • 为简化起见,无需在下面分配另一个变量。

推荐阅读