Rubyの配列、ハッシュテーブルを表現するArray、Hashクラスの使い方若手エンジニア/初心者のためのRuby 2.1入門(3)(2/4 ページ)

» 2014年05月08日 18時00分 公開
[著:麻田優真、監修:山根剛司株式会社アジャイルウェア]

Arrayオブジェクトは配列だけではなく「スタック」「キュー」としても扱える

Array#push、Array#popでArrayオブジェクトを「スタック」のように使う

 Arrayオブジェクトは配列として扱われることが多いですが、Array#pushとArray#popを使うことで、「スタック」のように扱うこともできます。

[1] pry(main)> stack = []
=> []
[2] pry(main)> stack.push("alice")
=> ["alice"]
[3] pry(main)> stack.push("in")
=> ["alice", "in"]
[4] pry(main)> stack.push("wonderland")
=> ["alice", "in", "wonderland"]
[5] pry(main)> stack.pop
=> "wonderland"
[6] pry(main)> stack
=> ["alice", "in"]
[7] pry(main)> stack.pop
=> "in"
[8] pry(main)> stack.pop
=> "alice"
[9] pry(main)> stack
=> []

 [1]で空のArrayオブジェクトを変数stackに代入し、[2][3][4]でArray#pushを使うことで次々に文字列オブジェクトをスタックに積んでいます。

 この状態で[5]のようにArray#popを実行すると、stackの最後尾にある"wonderland"が返され、stackから"wonderland"が取り除かれたことが[6]で確認できます。

Array#shiftでArrayを「キュー」のように使う

 Arrayオブジェクトをスタックとして扱えるのと同様に、Array#shiftを使うことで、「(FIFO)キュー」のように扱えます。

[1] pry(main)> queue = []
=> []
[2] pry(main)> queue.push("alice")
=> ["alice"]
[3] pry(main)> queue.push("in")
=> ["alice", "in"]
[4] pry(main)> queue.push("wonderland")
=> ["alice", "in", "wonderland"]
[5] pry(main)> queue.shift
=> "alice"
[6] pry(main)> queue
=> ["in", "wonderland"]
[7] pry(main)> queue.shift
=> "in"
[8] pry(main)> queue.shift
=> "wonderland"
[9] pry(main)> queue
=> []

 [1]で空のArrayオブジェクトを変数queueに代入し、[2][3][4]でArray#pushを使うことで次々に文字列オブジェクトをキューに詰めています。

 この状態で[5]にようにArray#shiftを実行すると、queueの先頭にある"alice"が返され、queueから"alice"が取り除かれたことが[6]で確認できます。

オブジェクトの順序に関連するArrayのメソッド

Array#reverseとArray#reverse!でオブジェクトを逆順に並び替える

 Array#reverseやArray#reverse!を使うと、含まれているオブジェクトを逆順に並べたArrayオブジェクトを新たに生成します。Array#reverseは逆順にしたArrayをオブジェクトを返し、自身の順序は変更しません。対するArray#reverse!は、逆順にしたArrayオブジェクトを自分自身に代入します。

[1] pry(main)> array = [1, 2, 3]
=> [1, 2, 3]
[2] pry(main)> array.reverse
=> [3, 2, 1]
[3] pry(main)> array
=> [1, 2, 3]
[4] pry(main)> array.reverse!
=> [3, 2, 1]
[5] pry(main)> array
=> [3, 2, 1]

 [1]では、配列リテラルを使って3つのオブジェクトを持つArrayをオブジェクトを生成、arrayに代入しています。[2]では、Array#reverseによってarrayを逆順に並び替えているため、[3, 2, 1]という配列が返ってきますが、arrayそのものに変更は加えないため、[3]のようにarrayは`[1, 2, 3]`のままです。Array#reverse!は、実行したオブジェクト自身を更新するため、[5]でarrayは`[3, 2, 1]`となっています。

補足「破壊的メソッド」

 Rubyの組み込みライブラリには、Array#reverseとArray#reverse!のような関係を持つメソッドがたくさんあります。ビックリマーク(エクスクラメーションマーク)の付いているメソッドは「破壊的メソッド」と呼ばれ、実行したオブジェクト自身の状態を変えるようなメソッドになっています。

 これはあくまで慣例です。もちろん、破壊的でないメソッドにビックリマークを付けることもできますが、利用者にとって不便なだけです。もしあなたがライブラリを設計する場合は、利用者を困惑させないためにも、この慣例を守るようにしましょう。


Array#rotate、Array#rotate!で配列を「ずらす」

 Array#rotateを使うと、引数に指定したインデックスを先頭としたArrayオブジェクトを新たに生成できます。Array#rotate!はArray#rotateの破壊的メソッド版です。配列を「ずらす」と考えると分かりやすいでしょう。

[1] pry(main)> array = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
[2] pry(main)> array.rotate(2)
=> [3, 4, 5, 1, 2]
[3] pry(main)> array.rotate(-2)
=> [4, 5, 1, 2, 3]

 [2]では、0から数えて2番目の要素、つまり3が先頭となるArrayオブジェクトが返されています。[3]のように、インデックスの指定には負の数を使うこともできます。

Array#sort_by、Array#sort_by!で配列をソートする

 Array#sort_byを使うと、配列をソート(並び替え)できます。Array#sort_by!はArray#sort_byの破壊的メソッド版です。要素同士の比較には「<=>」演算子が用いられます。

[1] pry(main)> [1, 5, 3, 2, 0, -5].sort_by
=> [-5, 0, 1, 2, 3, 5]

 Array#sortやArray#sort!といったメソッドも利用できますが、一般にArray#sort_byの方が高速です。

補足「宇宙船演算子」

 「<=>」は、その形状から「宇宙船演算子」と呼ばれる演算子で、「左辺 < 右辺」であれば-1を、「左辺 > 右辺」であれば1を、等しければ0を返す演算子です。宇宙船演算子は、整数や実数、以降の連載で紹介するTimeオブジェクトなど、さまざまなクラスのオブジェクトで利用できます。

[1] pry(main)> 1 <=> 2
=> -1
[2] pry(main)> 2 <=> 1
=> 1
[3] pry(main)> 1 <=> 1
=> 0

 余談ですが、この愛らしい形状とそのネーミングから、筆者の好きな演算子の一つです。


Array#shuffle、Array#shuffle!で配列をランダムに並び替える

 Array#shuffleを使うと、ランダムに並び替えたような配列を得ることができます。Array#shuffle!はArray#shuffleの破壊的メソッド版です。乱数を使って生成されるので、以下の実行結果は毎回変わります。

[1] pry(main)> array = ["queen", "of", "hearts"]
=> ["queen", "of", "hearts"]
[2] pry(main)> array.shuffle
=> ["queen", "of", "hearts"]
[3] pry(main)> array.shuffle
=> ["of", "queen", "hearts"]
[4] pry(main)> array.shuffle
=> ["queen", "of", "hearts"]

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。