プログラミングで文字列操作と同じくらいよく扱うのが、配列やリストの操作です。
複数のデータを管理する配列やリストには、様々な種類があり、用途に応じて使い分けることが重要となります。
本記事では、Rubyの配列・リストについて、種類と操作方法をまとめました。
プログラミング初心者の方の学習や、忘れてしまった方の復習として、参考にしていただければ幸いです。
記載しているプログラムは、Ruby2.7.1を使って動作確認をしています。
Rubyの配列・リスト操作
配列・リスト操作として、以下の内容をとりあげます。
- 配列・リストの種類
- 配列・リストの作成
- 配列・リストから値を取得する
- 配列・リストの長さ(要素数)を取得する
- 配列・リストに要素を追加する
- 配列・リストから要素を削除する
- 配列・リストをコピーする
- 配列・リストをループさせる
- 配列・リストの順番を入れ替える
- 配列・リスト同士を結合する
- 配列・リストを検索する
配列・リストの種類
複数のデータを管理する配列やリストは、プログラミング言語によって様々なデータ構造がサポートされています。
Rubyでは、以下の3種類を扱うことができます。
- Array(配列):1つの要素に1つのデータが入る。インデックスは番号で管理される。
- Hash(連想配列):keyとvalueで1つの要素を管理する。キーが追加された順番で順序が保証される。
- Set(集合):重複しない要素を管理する。要素間に順序関係はない。
今回は主に、Arrayに関する操作を中心にまとめていきます。
配列・リストの作成
Arrayの作成は、[]内に直接値を指定します。型が異なる要素同士を含めることも可能です。
a = ["Hello", "Ruby"] puts a.inspect # -> ["Hello", "Ruby"]
Hash作成は、{}内にkeyとvalueを指定します。
h = {1 => "Hello", 2 => "Ruby"} puts h # -> {1=>"Hello", 2=>"Ruby"}
集合はの作成は、Set[]に値を指定します。
Setは組み込みライブラリなので、requireが必要となります。
require 'set' s = Set["Hello", "Ruby"] puts s # -> #<Set: {"Hello", "Ruby"}>
配列・リストから値を取得する
Arrayから値を取得するには、取得したい要素のインデックスを指定します。
a = ["Hello", "Ruby"] r = a[1] puts r # -> Ruby
Hashから値を取得には、[]にキーを指定するか、fetchを使います。
h = {1 => "Hello", 2 => "Ruby"} r = h[2] puts r # -> Ruby
h = {1 => "Hello", 2 => "Ruby"} r = h.fetch(2) puts r # -> Ruby
Setから値を取得するには、Arrayに変換後、要素のインデックスを指定します。
Arrayへの変換時の順序は不定です。
s = Set["Hello", "Ruby"] r = s.to_a[1] puts r # -> Ruby
配列・リストの長さ(要素数)を取得する
Arrayの長さを取得するには、sizeまたはlengthを使います。
a = ["Hello", "Ruby"] r = a.size puts r # -> 2
Hashの長さを取得するには、sizeまたはlengthを使います。
h = {1 => "Hello", 2 => "Ruby"} r = h.size puts r # -> 2
Setの長さを取得するには、sizeまたはlengthを使います。
s = Set["Hello", "Ruby"] r = s.size puts r # -> 2
配列・リストに要素を追加する
Arrayの末尾に要素を追加するには、pushまたは<<を使います。
a = ["Hello", "Ruby"] r = a.push("!!") puts r.inspect # -> ["Hello", "Ruby", "!!"]
a = ["Hello", "Ruby"] r = a << "!!" puts r.inspect # -> ["Hello", "Ruby", "!!"]
Arrayの任意の場所に要素を追加するには、insertを使います。
第1引数に追加したいインデックスを、第2引数に追加したい要素を指定します。
a = ["Hello", "Ruby"] r = a.insert(1, "World") puts r.inspect # -> ["Hello", "World", "Ruby"]
Arrayの先頭に要素を追加するには、unshiftを使います。
a = ["Hello", "Ruby"] r = a.unshift("ABC") puts r.inspect # -> ["ABC", "Hello", "Ruby"]
Hashへの要素の追加は、keyとvalueを直接指定する方法と、storeを使う方法があります。
h = {1 => "Hello", 2 => "Ruby"} h[3] = "!!" puts h # -> {1=>"Hello", 2=>"Ruby", 3=>"!!"}
h = {1 => "Hello", 2 => "Ruby"} h.store(3, "!!") puts h # -> {1=>"Hello", 2=>"Ruby", 3=>"!!"}
Setへの要素の追加は、addまたは<<を使います。
s = Set["Hello", "Ruby"] s.add("ABC") puts s # -> #<Set: {"Hello", "Ruby", "ABC"}>
s = Set["Hello", "Ruby"] s << "ABC" puts s # -> #<Set: {"Hello", "Ruby", "ABC"}>
配列・リストから要素を削除する
Arrayから要素を削除するには、pop、shift、delete、delete_at、clearを使う方法があります。
popは、Arrayの末尾から要素を削除します。
a = ["Hello", "World", "Ruby"] a.pop puts a.inspect # -> ["Hello", "World"]
shiftは、Arrayの先頭から要素を削除します。
a = ["Hello", "World", "Ruby"] a.shift puts a.inspect # -> ["World", "Ruby"]
deleteは、指定した値と一致するArrayの要素を削除します。
a = ["Hello", "World", "Ruby"] a.delete("World") puts a.inspect # -> ["Hello", "Ruby"]
delete_atは、指定したインデックスのArrayの要素を削除します。
a = ["Hello", "World", "Ruby"] a.delete_at(1) puts a.inspect # -> ["Hello", "Ruby"]
clearは、Arrayのすべての要素を削除します。
a = ["Hello", "World", "Ruby"] a.clear puts a.inspect # -> []
Hashから要素を削除するには、delete、shift、clearを使う方法があります。
deleteは、削除するkeyを指定します。
h = {1 => "Hello", 2 => "Ruby"} h.delete(1) puts h # -> {2=>"Ruby"}
shiftは、先頭の要素を削除します。
h = {1 => "Hello", 2 => "Ruby"} h.shift puts h # -> {2=>"Ruby"}
clearは、Hashの要素をすべて削除します。
h = {1 => "Hello", 2 => "Ruby"} h.clear puts h # -> {}
Setから要素を削除するには、delete、clearを使う方法があります。
deleteは、削除する値を指定します。
s = Set["Hello", "Ruby"] s.delete("Hello") puts s # -> #<Set: {"Ruby"}>
clearは、Setの要素をすべて削除します。
s = Set["Hello", "Ruby"] s.clear puts s # -> #<Set: {}>
配列・リストをコピーする
Arrayをコピーするには、dupを使う方法とcloneを使う方法があります。
cloneはfrozen、tainted、singleton-classの情報を含めてコピーしますが、dupは内容だけをコピーします。
どちらも浅いコピーになります。
a = ["Hello", "World", "Ruby"] r = a.dup puts a.inspect # -> ["Hello", "World", "Ruby"]
a = ["Hello", "World", "Ruby"] r = a.clone puts a.inspect # -> ["Hello", "World", "Ruby"]
Hashをコピーするには、dupを使う方法とcloneを使う方法があります。
cloneはfrozen、tainted、singleton-classの情報を含めてコピーしますが、dupは内容だけをコピーします。
どちらも浅いコピーになります。
h = {1 => "Hello", 2 => "Ruby"} r = h.dup puts r # -> {1=>"Hello", 2=>"Ruby"}
h = {1 => "Hello", 2 => "Ruby"} r = h.clone puts r # -> {1=>"Hello", 2=>"Ruby"}
Setをコピーするには、dupを使う方法とcloneを使う方法があります。
dupは、集合の内容とtaint情報をコピーします。cloneでは加えて、freezeと特異メソッドをコピーします。
配列・リストをループさせる
Arrayをループさせるには、for-in、eachを使う方法があります。
また、インデックスに対してループするeach_indexやeach_with_index、逆順にループするreverse_eachがあります。
a = ["Hello", "World", "Ruby"] for r in a do puts r # -> Hello -> World -> Ruby end
a = ["Hello", "World", "Ruby"] a.each do |r| puts r # -> Hello -> World -> Ruby end
a = ["Hello", "World", "Ruby"] a.each_index do |r| puts r # -> 0 -> 1 -> 2 end
a = ["Hello", "World", "Ruby"] a.each_with_index do |value, index| puts "#{index} #{value}" # -> 0 Hello -> 1 World -> 2 Ruby end
a = ["Hello", "World", "Ruby"] a.reverse_each do |r| puts r # -> Ruby -> World -> Hello end
Hashをループさせるには、eachを使います。
keyだけをループさせるeach_keyやvalueだけをループさせるeach_valueもあります。
h = {1 => "Hello", 2 => "Ruby"} h.each do |key, value| puts "#{key} #{value}" # -> 1 Hello -> 2 Ruby end
Setをループさせるには、for-inやeachを使います。
配列・リストの順番を入れ替える
Arrayの要素を入れ替えるには、sort、rotate、shuffle、reverseがあります。
sortは、要素をソートします。要素同士の比較は、<=>演算子を使って行われます。
a = ["Hello", "World", "Ruby"] r = a.sort puts r.inspect # -> ["Hello", "Ruby", "World"]
rotateは、指定したインデックスが先頭になるようにします。それより前の要素は末尾に移動します。
a = ["Hello", "World", "Ruby"] r = a.rotate puts r.inspect # -> ["World", "Ruby", "Hello"]
shuffleは、要素をランダムにシャッフルします。
a = ["Hello", "World", "Ruby"] r = a.shuffle puts r.inspect # -> ["World", "Hello", "Ruby"]
reverseは、要素を逆順に並べ替えます。
a = ["Hello", "World", "Ruby"] r = a.reverse puts r.inspect # -> ["Ruby", "World", "Hello"]
Hashのkeyとvalueを入れ替えるには、invertを使います。
h = {1 => "Hello", 2 => "Ruby"} r = h.invert puts r # -> {"Hello"=>1, "Ruby"=>2}
配列・リスト同士を結合する
Arrayを結合するには、concatを使う方法と+演算子を使う方法があります。
a1 = ["Hello", "World"] a2 = ["Ruby", "!!"] r = a1.concat(a2) puts r.inspect # -> ["Hello", "World", "Ruby", "!!"]
a1 = ["Hello", "World"] a2 = ["Ruby", "!!"] r = a1 + a2 puts r.inspect # -> ["Hello", "World", "Ruby", "!!"]
Hashを結合するには、mergeを使います。
h1 = {1 => "Hello", 2 => "World"} h2 = {3 => "Ruby", 4 => "!!"} r = h1.merge(h2) puts r # -> {1=>"Hello", 2=>"World", 3=>"Ruby", 4=>"!!"}
Setを結合するには、mergeを使います。
s1 = Set["Hello", "World"] s2 = Set["Ruby", "!!"] r = s1.merge(s2) puts r # -> #<Set: {"Hello", "World", "Ruby", "!!"}>
配列・リストを検索する
Arrayから特定の値を検索するには、include?、indexを使います。
include?は指定した値が含まれていればtrueを返します。含まれていない場合はfalseを返します。
a = ["Hello", "World", "Ruby"] r = a.include?("Ruby") puts r # -> true
indexは指定した値が含まれていれば、見つかった最初のインデックスを返します。
a = ["Hello", "World", "Ruby"] r = a.index("Ruby") puts r # -> 2
Hashから特定の値を検索するには、include?、indexの他に、has_key?、key?を使うことができます。
また、valueに対する検索として、has_value?やvalue?を使うことができます。
Setから特定の値を検索するには、include?の他に、member?を使うことができます。
配列・リストの操作はやりたい処理によって使うメソッドを変えよう
配列やリストの操作には、同じ結果を得られる方法が、処理を組み合わせることによって何通りもあります。
ですが、特にループを伴う場合には、処理の仕方によってはパフォーマンスが悪いこともあります。
どんなメソッドを使うのかは、やりたい処理によって適宜変えられるように、日頃からたくさん引出しを持っておくことをおすすめします。
今回は、Rubyの配列・リスト操作についてまとめました。
参考になれば幸いです。
コメント