ruby中的标准方法与(1...4).to_a
类似[1,2,3,4]
除了反向,(4...1).to_a
是[4,3,2,1]
吗?
我意识到这可以很容易地通过(1...4).to_a.reverse
来定义,但它让我感到奇怪的是它已经不存在而且 1)我错过了什么? 2)如果没有,是否还有功能/实际原因?
答案 0 :(得分:9)
最简单的可能就是:
4.downto(1).to_a #=> [4, 3, 2, 1]
或者,您可以使用step
:
4.step(1,-1).to_a #=> [4, 3, 2, 1]
最后一个相当模糊的解决方案:
(-4..-1).map(&:abs) #=> [4, 3, 2, 1]
答案 1 :(得分:8)
(1...4)
是一个范围。红宝石中的范围与数组不同;一个,如果他们的优势是你可以创建像
(1..1e9)
不占用机器的所有内存。此外,您可以创建此范围:
r = (1.0...4.0)
这意味着“所有浮点数的集合从1.0到4.0,包括1.0但不是4.0”
换句话说:
irb(main):013:0> r.include? 3.9999
=> true
irb(main):014:0> r.include? 3.99999999999
=> true
irb(main):015:0> r.include? 4.0
=> false
您可以将整数范围转换为数组:
irb(main):022:0> (1..4).to_a
=> [1, 2, 3, 4]
但不是浮点范围:
irb(main):023:0> (1.0...4.0).to_a
TypeError: can't iterate from Float
from (irb):23:in `each'
from (irb):23:in `to_a'
from (irb):23
from /home/mslade/rubygems1.9/bin/irb:12:in `<main>'
因为没有自然的方法来迭代浮点数。而是使用#step
:
irb(main):015:0> (1..4).step(0.5).to_a
=> [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0]
irb(main):016:0> (1...4).step(0.5).to_a
=> [1.0, 1.5, 2.0, 2.5, 3.0, 3.5]
如果需要向后迭代一个大的整数范围,请使用Integer#downto
。
答案 2 :(得分:1)
您可以修改Range#to_a以自动使用反向操作:
class Range
alias :to_a_original :to_a
def reverse
Range.new(last, first)
end
def to_a
(first < last) ? to_a_original : reverse.to_a_original.reverse
end
end
结果:
(4..1).to_a
=> [4, 3, 2, 1]
这种方法被称为“重新开放”类a.k.a.“monkey-patching”。一些开发人员喜欢这种方法,因为它添加了有用的功能,有些人不喜欢它,因为它正在弄乱Ruby核心。)