2011-03-11 53 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