3

ruby 中是否有类似于(1...4).to_ais的标准方法,[1,2,3,4]除了反向 ie(4...1).to_a会是[4,3,2,1]吗?

我意识到这可以很容易地定义,(1...4).to_a.reverse但让我感到奇怪的是它还没有,而且1)我错过了什么吗?2)如果没有,是否有功能/实际原因还没有?

4

3 回答 3

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]
于 2012-04-06T07:12:03.603 回答
8

(1...4)是一个范围。ruby 中的范围不像数组。如果他们的优势是您可以创建一个范围,例如

(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.

于 2012-04-06T06:49:21.840 回答
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]

这种方法称为“重新打开”类,也称为“猴子补丁”。有些开发人员喜欢这种方法,因为它添加了有用的功能,有些人不喜欢它,因为它与 Ruby 核心混淆。)

于 2012-04-06T07:08:45.060 回答