我正在尝试创建一种计算包裹运费的方法。运费来自表格,其中列出了重量范围和相应的价格。
示例数据:
0 - 50g : $1
51 - 100g : $2
我应该如何构建数据,如何根据数据动态生成价格而不是编写许多if
语句?
示例代码:
def price_for_weight(w)
if w < 50
return 1
elsif w < 100
return 2
end
答案 0 :(得分:2)
您可以这样做的一种方法是将数据结构化为Hash
,并将Range
个对象作为键,如下所示:
SHIPPING_COSTS = {
0..50 => 1,
51..100 => 2,
}
在您的方法中使用Enumerable#select
,然后您可以使用===
运算符获取键值对:
def price_for_weight(w)
SHIPPING_COSTS.select { |range| range === w }
end
与集合一起使用的 ===
会询问比较右侧的值是否可以被视为左侧集合的成员(请参阅this question)。
由于上面会返回一个键值对,你可以在块之后添加.values.first
以获得成本:
def price_for_weight(w)
SHIPPING_COSTS.select { |range| range === w }.values.first
end
答案 1 :(得分:1)
假设成本并不总是全部美元,以美分计算会更好。
ShippingCost = {50 => 100, 100 => 200}
def price_for_weight(w)
ShippingCost[ShippingCost.keys.bsearch{|k| w <= k}]
end
答案 2 :(得分:0)
以下是另一种方法:
鉴于你的范围来自DB,你将使用一些东西。我们可以使用散列来表示每个价格范围的值,如下所示。
prices = [ {min: 0, max: 50, price: 1}, {min: 50, max: 100, price: 2} ]
weight = 50.5
prices.find {|i| (i[:min]...i[:max]).include? weight }[:price]
#=> 2
另请注意范围内...
的使用情况,其中不包括结束值。因此,(0...50)
不会包含50
。如果您使用(0..50)
,(50..100)
,或者如果您使用了(0..50)
和(51..100)
,我们就不会跳过一系列值,这样可以确保范围之间没有重叠{1}}。