2011-03-11 11 views

答えて

11

あなたrequire 'backports/1.9.2/array/rotate'場合は、あなたが得るをArray#rotaterotate!古いバージョンのRubyでは

いずれにしても、ホイールの再発明を避けることができます。さらに重要なことに、RubySpecを渡す実装の利点を得ることができます。すべてのコーナーケースで動作し、Ruby 1.9との互換性を保証します。

たとえば、[]の2つの回答はどちらも機能しません。

+0

Cygwinから作業していた場合、どのようにバックポートを組み込むのですか? –

+0

バックポートは宝石ですので、インストール手順に従って 'バックポートをインストールする '必要があります。 –

+0

ありがとう、私は宝石をインストールして使用しました。 Cygwinは、デフォルトのパッケージに入っていないものをイライラするようにします。 –

9

a.push(a.shift)と同じことができます。基本的に最初の要素を削除し(シフト)、最後に追加します(プッシュ)。

+0

元の配列も変更されますが、元の配列は変更されません。 – rubyprince

+0

これは、 'rotate!'の場合は配列を変更しますが、 '[]'の場合は失敗します。また、1.9とはあまり互換性がありません。なぜなら、回転させる要素の数を引数に取ることができないからです。私の答えを見てください。 –

1

回転のために!パラメータを指定しないと、gnabは正常です。

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

nは、配列の長さよりも大きくなる可能性がある場合:あなたは、オプションのパラメータを持つ非破壊1、必要な場合

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

どちらも '[]'に失敗します。私の答えを見てください。 –

+0

私はMarc-Andreの指摘の後で2番目の例を修正しましたが、私は 'backports'がより良くなることに同意します。私はそれがおそらく役に立たないので、最初のものを修正しませんでした。 – sawa

2

パーティへの道遅刻のような何も...。a.rotate!(n)と同様に)

a += a.shift(n) 

そして、それはa = []で動作します。ただし、a.rotate!(n)とは異なり、nが長さがaより大きい場合は何も行いません。

以下はaの値を保持し、a.lengthよりn大きいが、もう少し手の込んだことを犠牲にして、作業することができ:

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

あなたの 'rotate'バージョンは元の配列' a'を変更します – rubyprince

+0

@rubyprinceああ、確かにそうです。 Rubyのメソッド定義には少し矛盾があると私は思う。私は 'shift'はArrayだけを残すべきだと思うし、実際に直接変更するには' shift! 'が必要です。 – lurker

+0

'shift'メソッドはシフトされた要素を実際に返し、元の配列をシフトします。非常に便利。 – rubyprince

関連する問題