2011-03-11 65 views

回答

11

如果require 'backports/1.9.2/array/rotate',你会得到Array#rotaterotate!在旧版本的Ruby中。无论哪种方式,您都避免重新发明轮子,更重要的是您获得了通过RubySpec的实现的优势。它将适用于所有的角落案例,并确保与Ruby 1.9的兼容性。

例如,两个答案都没有给出[]的工作!

+0

如果我在Cygwin工作,我将如何包含backports? – 2012-01-14 00:10:45

+0

Backports是一个宝石,所以你需要按照安装说明'gem install backports'。 – 2012-01-14 03:19:02

+0

谢谢,我安装并使用了精美的宝石; Cygwin使安装的东西不在默认包中令人沮丧。 – 2012-01-14 04:23:37

9

你可以用a.push(a.shift)来实现。它基本上删除第一个元素(shift)并将其追加到最后(push)。

+0

但它改变了原来的数组也有..有没有办法改变原来的数组? – rubyprince 2011-03-11 07:27:09

+0

这将用于'rotate!',它改变了数组,但是它失败了[]'。它与1.9也不完全兼容,因为它不接受有多少元素旋转的参数。看到我的答案。 – 2011-03-11 15:44:01

1

对于旋转!没有参数的版本,gnab的很好。如果你想在非破坏性之一,带有可选参数:

class Array 
    def rotate n = 1; self[n..-1]+self[0...n] end 
end 

如果n可能变得比数组的长度更大:

class Array 
    def rotate n = 1; return self if empty?; n %= length; self[n..-1]+self[0...n] end 
end 
+0

这两个都失败了'[]'。看到我的答案。 – 2011-03-11 15:42:44

+0

我在Marc-Andre的观点之后修正了第二个例子,但我同意'backports'会更好。我没有修复第一个,因为它可能没用。 – sawa 2011-03-11 17:35:24

2

没有像未来路迟到了...;)

类似a.rotate!(n)

a += a.shift(n) 

而且它与a = []工作。但是,与a.rotate!(n)不同,如果n大于a的长度,则不会执行任何操作。

下保存的a价值和能够n大于a.length工作,在被多一点精致的费用:

a.last(a.length - (n % a.length)) + a.first(n % a.length) 

这显然是最好的,如果n % a.length单独计算一次,整个事情包裹在一个方法猴子修补成Array

class Array 
    def rot(n) 
    m = n % self.length 
    self.last(self.length - m) + self.first(m) 
    end 
end 
+0

你的'旋转'版本确实改变了原始数组'a' – rubyprince 2014-05-26 07:00:48

+0

@rubyprince啊是的,的确如此。我认为Ruby的方法定义有点不一致。我认为'shift'应该单独离开数组,并且他们应该有一个'shift!'来直接修改它。 – lurker 2014-05-26 10:50:22

+0

'shift'方法实际上会返回移位的元素,并且会移动原始数组。很有用。 – rubyprince 2014-05-27 05:19:40