Rubyの配列(array)をマスターしよう!配列のメソッド・使い方を解説!



Rubyの配列(array)をマスターしよう!配列のメソッド・使い方を解説!

image

目次
  1. Rubyの配列(array)とは?
  2. 配列の作成方法
  3. 配列の要素の取り出し方
  4. 配列の宣言
  5. 配列から要素を取り出す
  6. 配列の最後の要素を取り出す
  7. 配列の最後から2番めの要素を取り出す
  8. 配列の先頭の要素を取り出す
  9. 配列の最後の要素を取り出す
  10. 配列の先頭から2つ要素を取り出す
  11. 配列の最後から2つ要素を取り出す
  12. 配列の先頭の要素を取り出す
  13. 配列の最後の要素を取り出す
  14. 配列の先頭から2つ要素を取り出す
  15. 配列の最後から2つ要素を取り出す
  16. 配列に対するループ
  17. eachメソッド
  18. 配列の宣言
  19. 配列に対してループ処理を行う
  20. each_with_indexメソッド
  21. 配列の宣言
  22. 配列に対してループ処理を行う
  23. map/collectメソッド
  24. 1〜 6までの値を持つ配列を宣言
  25. 全ての要素を3倍にする
  26. 配列の要素の追加方法
  27. << 演算子
  28. pushメソッド
  29. concatメソッド
  30. 配列の長さを取得する
  31. 配列から要素を検索する
  32. select/find_allメソッド
  33. 1〜 6までの値を持つ配列を宣言
  34. 偶数(2で割り切れる)を取り出す
  35. selectメソッド同様の結果
  36. rejectメソッド
  37. 1〜 6までの値を持つ配列を宣言
  38. 奇数(2で割り切れない)を取り出す
  39. detect/findメソッド
  40. 1〜 6までの値を持つ配列を宣言
  41. 偶数(2で割り切れる)を取り出す(ただし最初にtrueになった要素のみ)
  42. detectメソッドと同様の結果
  43. 配列のその他のメソッド
  44. include?メソッド
  45. compactメソッド
  46. join
  47. 配列を宣言
  48. 配列の要素を連結して文字列として返却します
  49. 配列の要素を引数の文字列を区切りとして連結します
  50. join (引数なし)
  51. join (引数あり)
  52. 配列の配列(多重配列)
  53. 配列の配列
  54. 配列の配列の配列
  55. flattenメソッド
  56. 配列の配列
  57. 配列の配列の配列
  58. 2次元配列を1次元へ
  59. 3次元配列を1次元へ
  60. 配列の配列
  61. 配列の配列の配列

Rubyの配列(array)とは?

Rubyの変数について理解を深めよう!変数の種類やスコープについて解説にて変数について解説しましたが、変数が「何かを入れておく、名前の付いた箱」なのに対し、配列は「箱が順番に並んだグループ」と言えます。 また、変数は箱1つに対して名前を付けていましたが、配列は箱がならんだものを1つのグループとして名前をつけます。また、配列はarrayとしばしば呼ばれることもあります。

下記のようなイメージです。

「箱グループ」

箱1 箱2 箱3 箱4 箱5
値1 値2 値3 値4 値5

上記の値1〜値5までの配列の各箱に入っている値のことを要素と呼びます。 また、配列には0から順番に番号が割り当てられており、それをプログラミングでは添字(またはインデックス)と呼びます。下記のようなイメージです。

「箱グループ」

0 1 2 3 4
値1 値2 値3 値4 値5

ここで、注意が必要なのが添字は0から始まっているということです。 箱1が添字0となり、箱5が添字4と対応していることがわかります。

配列の作成方法

続いて、配列の作成方法を解説させていただきます。Rubyにおいて配列を作成する場合は括弧( [] )を使用します。また変数(箱)を複数用意する際は、括弧の中に値をカンマ区切りで記述していきます。

# ①
fruite = ['orange']

# ②
fruits = ['lemon', 'banana', 'apple']

①が値が一つの配列、②が値が複数ある配列となります。①、②で要素の数に違いはありますが、共に配列となります。上記が、Rubyにおける配列の作成方法の中で最も簡易的なものになります。

また、値が無い配列を宣言することも可能です。

fruites = []

上記の用に括弧([])だけで宣言した場合は要素が1つもない状態となります。 下記のように同じ配列の中に別の型を入れることも可能です。

fruits = ['lemon', 'banana', 'apple', 123]

ただし、配列にはどのような値が含まれているかは、中の要素を取り出してみないと確認できないため、このように型が異なる要素が含まれていると、思わぬ不具合に繋がる可能性があります。

配列の要素の取り出し方

配列から要素を取り出す際は、下記のように添字(インデックス)を指定します。

# 配列の宣言
fruits = ['lemon', 'banana', 'apple']

# 配列から要素を取り出す
fruits[0]
fruits[1]
fruits[2]

# 配列の最後の要素を取り出す
fruits[-1]

# 配列の最後から2番めの要素を取り出す
fruits[-2]

配列の添字に負の数値を指定すると、逆順(配列の末尾)で配列を操作することが可能です。その際は、0〜ではなく-1〜であることに注意して下さい。

また、添字を指定する以外にも下記のように、メソッドを使用することで要素を取り出すことも可能です。

# 配列の先頭の要素を取り出す
fruits.first

# 配列の最後の要素を取り出す
fruits.last

# 配列の先頭から2つ要素を取り出す
fruits.first(2)

# 配列の最後から2つ要素を取り出す
fruits.last(2)

出力結果

# 配列の先頭の要素を取り出す
'lemon'

# 配列の最後の要素を取り出す
'apple'

# 配列の先頭から2つ要素を取り出す
['lemon', 'banana']

# 配列の最後から2つ要素を取り出す
['banana', 'apple']

上記のメソッドはとても便利なので個人的にはよく使用しています。firstメソッドやlastメソッドは引数を指定することが可能であり、引数の数値分の要素を取り出すことができます。

配列に対するループ

作成した配列に対して、繰り返し同様の処理を行いたい場合がしばしばあるかと思います。そういった際には、配列に対してループ処理を実施することで実現できます。

eachメソッド

配列にはeachメソッドという繰り返し処理を行う際のメソッドが用意されています。 文法としては下記のとおりです。

配列オブジェクト.each { |変数|
  実行する処理1
  実行する処理2
  ...
}

具体的には下記のようになります。

# 配列の宣言
fruits = ['lemon', 'banana', 'apple']

# 配列に対してループ処理を行う
fruits.each { |fruite|

  # 実行する処理1
  p fruite
}

上記のようにeachメソッドは{}で囲まれた範囲を引数とします。またこの{}で囲まれた範囲をブロックといいます。また、|fruite| のように パイプ( | )で囲まれた値をブロック引数(またはブロックパラメータ)と呼びます。今回でいうとfruiteがブロック引数となります。

eachメソッドは配列の要素ごとにブロック内の処理を実行します。また、その際の要素の値がブロック引数に渡ります。つまり、eachの1度目の処理は、配列fruitsの添字0番目の要素がfruiteというブロック引数に渡されるため、処理結果としては'lemon'という文字列がpメソッドにより表示されることになります。

同様に2番め、3番目...と全ての要素に対して処理が終わるまでループ処理が行われます。

また、ブロックは{}ではなくdoとendに置き換えることができます。

配列オブジェクト.each do |変数|
  実行する処理1
  実行する処理2
  ...
end

each_with_indexメソッド

eachメソッドと使い方は同じなのですが、each_with_indexメソッドは下記のようにブロック引数を2つ取ることができます。

# 配列の宣言
fruits = ['lemon', 'banana', 'apple']

# 配列に対してループ処理を行う
fruits.each_with_index { |fruite, i|

  # 実行する処理1
  p fruite

  # 実行する処理2
  p i
}

上記の場合だと、1つ目のブロック引数がfruiteで配列の各要素を表します。配列の添字(インデックス)が2つ目のブロック引数には添字の番号が入ります。 つまり、1度目のループ処理ではiは0、2度目のループ処理ではiには1が入ります。

例えば、偶数の要素には処理を行いたくない場合や、規定の回数ループ処理を行いたい場合などに有効です。

map/collectメソッド

eachメソッド同様、mapやcollectといったメソッドがあり、これらはブロック内の式を実行した結果を返します。また、mapメソッドとcollectメソッドは同様の結果となります。

# 1〜 6までの値を持つ配列を宣言
numbers = [1, 2, 3, 4, 5, 6]

# 全ての要素を3倍にする
p numbers.map { |n| n * 3 }

出力結果

[3, 6, 9, 12, 15, 18]

eachメソッドとの違いは、mapメソッドはブロックごとに処理された結果(戻り値)を集めた配列を返します。

配列の要素の追加方法

<< 演算子

配列に新しく要素を追加する場合は下記のように<< 演算子を使用します。

fruits = ['lemon', 'banana', 'apple']
fruits << 'raspberry'

上記の結果として、配列fruitsの末尾に'raspberry'が追加されました。<<演算子を使用することで、末尾に要素を追加することができます。

pushメソッド

<<演算子以外にも、pushメソッドを使用することで、同じように配列の末尾に要素を追加することができます。

fruits = ['lemon', 'banana', 'apple']
fruits.push('raspberry')

上記の結果は<<演算子と同様の結果となります。また、pushメソッドは引数に複数の値を指定することができます。

pushメソッド(引数を複数指定)

fruits.push('raspberry', 'blueberry')

上記のように引数を複数指定し、同時に末尾に追加することも可能です。

concatメソッド

pushメソッドに複数の値を指定しましたが、同様の処理をconcatメソッドで代用することも可能です。

fruits = ['lemon', 'banana', 'apple']
p fruits.concat(['raspberry', 'blueberry'])

出力結果

['lemon', 'banana', 'apple', 'raspberry', 'blueberry']

pushメソッドの場合は複数の値を引数に指定しなければなりませんが、concatメソッドの場合は配列化した1つの値を指定するだけなので、配列同士を連結させる場合は、concatメソッドを使用するのが一般的です。

配列の長さを取得する

配列の長さ(要素の個数)を取得するには、lengthメソッドもしくはsizeメソッドを使用します。

fruits = ['lemon', 'banana', 'apple']
p fruits.length
p fruits.size

出力結果

3

上記の結果は、lengthメソッド、sizeメソッドの両方とも長さ(要素の個数)は3という数値を返却します。 lengthメソッドもsizeメソッドも動作は同じなので、利用する場合はどちらかに統一しましょう。

配列から要素を検索する

配列から要素を検索するにはいくつか方法があります。

select/find_allメソッド

配列の中から指定された値を持つ要素があるかどうかを検索するにはselectメソッドもしくはfind_allメソッドを使用します。lengthメソッドとsizeメソッド同様、こちらも検索する動作は全く同じです。

このselect/find_allメソッドですが、少々難しい記述をします。

# 1〜 6までの値を持つ配列を宣言
numbers = [1, 2, 3, 4, 5, 6]

# 偶数(2で割り切れる)を取り出す
p numbers.select { |n| n % 2 == 0 }

# selectメソッド同様の結果
p numbers.find_all { |n| n % 2 == 0 }

出力結果

[2, 4, 6]

上記のように、selectメソッドやfind_allメソッドはブロックを引数に指定する必要があります。 {}ブロック内の結果がtrueになった値のみを抽出することができます。なお、trueの結果が無かった場合は、空の配列( [] )が返却されます。

rejectメソッド

selectメソッドやfind_allメソッドは、指定された値を持つ要素があるかどうかを判定していましたが、ここで紹介するrejectメソッドはその逆で、指定された値を持たない要素のみを取り出します。

# 1〜 6までの値を持つ配列を宣言
numbers = [1, 2, 3, 4, 5, 6]

# 奇数(2で割り切れない)を取り出す
p numbers.reject { |n| n % 2 == 0 }

出力結果

[1, 3, 5]

selectメソッドやfind_allメソッド同様にブロックを引数に指定する必要があります。{}ブロックの結果falseになった値のみを抽出することができます。また同様にfalseの結果がなかった場合は空の配列( [] )が返却されます。

detect/findメソッド

detectメソッドやfindメソッドという配列の中から指定された値を取り出すメソッドも用意されています。利用方法としては、基本的にはselectメソッドやfind_allメソッドと同様なのですが、1点違いがあり、それは「ブロック内の式がtrueになった 最初の要素」のみを取り出すことです。

# 1〜 6までの値を持つ配列を宣言
numbers = [1, 2, 3, 4, 5, 6]

# 偶数(2で割り切れる)を取り出す(ただし最初にtrueになった要素のみ)
p numbers.detect { |n| n % 2 == 0 }

# detectメソッドと同様の結果
p numbers.find { |n| n % 2 == 0 }

出力結果

2

detectメソッドとfindメソッドは、trueの結果がない場合に、空の配列ではなくnilを返却することに注意してください。

配列のその他のメソッド

include?メソッド

incude?メソッドは配列内に指定した値を持つ要素があるかどうかを判定します。メソッドの後ろに疑問符( ? )がつくメソッドは基本的にはtrueかfalseを返却するので、このinclude?メソッドも同様、指定した要素が存在すればtrueなければfalseを返却します。

fruits = ['lemon', 'banana', 'apple']

if fruits.include?('raspberry')
  p 'ラズベリーはあります!'
end

compactメソッド

compactメソッドは、配列中に空の要素があればそれを除外した配列を返却します。

fruits = ['lemon', 'banana', 'apple', nil, nil, 'raspberry']
p fruits.compact

出力結果

['lemon', 'banana', 'apple', 'raspberry']

join

joinメソッドを使用することで、配列内の要素を文字列として連結することができます。

# 配列を宣言
fruits = ['lemon', 'banana', 'apple']

# 配列の要素を連結して文字列として返却します  
p fruits.join

# 配列の要素を引数の文字列を区切りとして連結します 
p fruits.join(',')

出力結果

# join (引数なし)
'lemonbananaapple'

# join (引数あり)
'lemon,banana,apple'

joinメソッドは配列内に文字列ではなく数値が含まれている場合も文字列として連結してくれます。

Rubyでのサービス開発スキルが身に付く

CodeCampの無料体験はこちら

配列の配列(多重配列)

配列は、要素として配列を持つことも可能です。下記のように、2次元3次元...と多重に配列化していくことも可能です。

# 配列の配列
foods = [['lemon', 'banana', 'apple'], ['ramen', 'soba', 'udon']]

# 配列の配列の配列
numbers = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]

ここまでややこしい配列を作成するくらいであれば、今回は解説いたしませんが、連想配列やHash(ハッシュ)を利用すると良いです。

flattenメソッド

多重化された配列を1次元(通常の配列)に整理することができるメソッドです。

# 配列の配列
foods = [['lemon', 'banana', 'apple'], ['ramen', 'soba', 'udon']]

# 配列の配列の配列
numbers = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]

# 2次元配列を1次元へ
p foods.flatten

# 3次元配列を1次元へ
p numbers.flatten

出力結果

# 配列の配列
["lemon", "banana", "apple", "ramen", "soba", "udon"]

# 配列の配列の配列
[1, 2, 3, 4, 5, 6, 7, 8]

以上が配列のメソッドやその使い方の解説になります。配列のメソッドはこれだけでもほんの一部です。特に同名のメソッドが結構あるのでご注意下さい。

また次回、配列との関連性が強い、連想配列やHash(ハッシュ)について解説させていただきます。

image

CodeCampus編集部
この記事を書いた人
CodeCampus編集部
\ 無料体験開催中!/自分のペースで確実に習得!
オンライン・プログラミングレッスンNo.1のCodeCamp