是否可以在ruby中使用解构来提取结束并从范围开始?
module PriceHelper
def price_range_human( range )
"$%s to $%s" % [range.begin, range.end].map(:number_to_currency)
end
end
我知道我可以使用数组强制作为一个非常糟糕的黑客:
first, *center, last = *rng
"$%s to $%s" % [first, last].map(:number_to_currency)
但有没有一种语法方法可以在不实际手动创建数组的情况下获取begin
和end
?
min, max = (1..10)
本来很棒。
答案 0 :(得分:4)
开始和结束?我会用:
foo = 1..2
foo.min # => 1
foo.max # => 2
尝试对范围使用解构是一个坏主意。想象一下可以生成然后丢弃的数组大小,浪费CPU时间和内存。如果您的范围以Float::INFINITY
结尾,那么它实际上是DOS自己代码的好方法。
end
与max
不同:在1 ... 10中,end
为10,但max
为9
那是因为start_val ... end_val
相当于start_val .. (end_val - 1)
:
start_value = 1
end_value = 2
foo = start_value...end_value
foo.end # => 2
foo.max # => 1
foo = start_value..(end_value - 1)
foo.end # => 1
foo.max # => 1
max
反映了Ruby在迭代范围或测试包含在范围内时实际使用的值的实际情况。
在我看来,end
应该反映在范围内将考虑的实际最大值,而不是在范围定义结束时使用的值,但我怀疑否则会改变它' d影响现有代码。
...
更容易混淆并导致维护问题增加,因此不建议使用它。
答案 1 :(得分:3)
您可以使用minmax
来构建简单范围:
min, max = (1..10).minmax
min # => 1
max # => 10
答案 2 :(得分:2)
不,在被Cary Swoveland,周刊世界新闻或其他小报证明不正确之前,我会继续相信没有任何证据表明答案是"没有" ;但它很容易制作。
module RangeWithBounds
refine Range do
def bounds
[self.begin, self.end]
end
end
end
module Test
using RangeWithBounds
r = (1..10)
b, e = *r.bounds
puts "#{b}..#{e}"
end
然后,我首先要写"#{r.begin.number_to_currency}..#{r.end.number_to_currency}"
。
答案 3 :(得分:0)
Amadan的答案很好。你只需要在使用它时删除splat(*),因为它不需要
例如
> "%s to %s" % (1..3).bounds.map{|x| number_to_currency(x)} => "$1.00 to $3.00"