Rubyの配列・リスト操作【プログラミング初心者向け教材】

プログラミング

プログラミングで文字列操作と同じくらいよく扱うのが、配列やリストの操作です。

複数のデータを管理する配列やリストには、様々な種類があり、用途に応じて使い分けることが重要となります。

本記事では、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-ineachを使う方法があります。
また、インデックスに対してループするeach_indexeach_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-ineachを使います。

配列・リストの順番を入れ替える

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の配列・リスト操作についてまとめました。

参考になれば幸いです。

コメント

タイトルとURLをコピーしました