これまで使っていた変数には値を一つしか入れていなかったが、
複数の値をまとめて扱うこともできる。
複数の値をまとめて保持するものが配列である。
Rubyでは、配列のことを Array
という。
たとえば、変数 x
を使う場合を考えてみる。
x = 5
とすると、x
という名前の箱に、
5という値ただ一つが入る(下図参照)。
x |
5 |
x
に配列を入れることにすると何個でも値を入れられる。
配列は複数の要素をカンマで区切って並べたものを
大括弧 [ ]
で括って表記する。
x = [5, 6, 3, 2, 9]
x
には、5つの値が順序よく並んだものが代入される。
x | ||||
5 | 6 | 3 | 2 | 9 |
試験の成績、売り上げ、などなど、計算機で処理したいと思う 「世の中にある数」は、どれも1個だけではない。ひとつの項目に 関する数が何件も存在するので、計算対象となる数は配列に 入れて処理するのが普通である。
上記の配列は、5個の値が並んだものである。配列に含まれる 一個一個の値のことを要素という。任意の位置の配列の要素に アクセスするには添字を付けて表現する。
x | ||||
x[0] | x[1] | x[2] | x[3] | x[4] |
5 | 6 | 3 | 2 | 9 |
変数の直後についている
[0]から[4]
の部分が添字で通常は0から始まる整数を指定する。
変数[添字]と書けば、「添字」のところに相当する要素を 参照することもできるし、そこに代入することもできる。
printf("x0=%d\n", x[0])
とすると、先頭要素である5が出力され、
x[4] = 10
とすると、(0から数えて)4番目(つまり末尾)の要素が10に変わり、 配列全体は
[5, 6, 3, 2, 10]
と変わる。
配列を持つ変数を添字なしで書くと配列全体を意味する。したがって、
y = x
とすると、変数y
に配列全体が代入される。
配列を利用する場合、最初から要素が何個になるか分かっているとは限らない。 Rubyでは必要に応じて配列の要素数を増やすことができる。 ある変数を配列として利用したい場合は、最初に要素数ゼロの空っぽ配列を代入する。 大括弧の中に何も書かないと「空の配列」を意味する。
x = []
この状態から以下のようにすれば配列に値を追加できる。
x[0] = "Hello!" x[1] = 5 x[2] = 3.1415
しかしながら
このように配列の末尾の添字を具体的に指定する方法はあまり使わず、
配列用のメソッド <<
で要素を末尾に順次追加するほうが利用しやすい。
x << "Hello!" x << 5 x << 3.1415 : (以下何個でも)
同じことは配列に備わるpush
メソッドを用いて
以下のようにも書ける。
x.push("Hello!") x.push(5) x.push(3.1415)
配列内の要素は、一つ一つ取り出して利用する。
要素の値だけを使うときは each
メソッドまたは
for
文を使用し、添字が必要なときは
each_with_index
メソッドまたはwhile
文を使う。
a = [9, 6, 4, 3, 2]
のときにa
に配列が入っている場合の繰り返し手順を以下に示す。
each
, for
each
メソッドで取り出し変数を指定して繰り返しa.each do |x| puts x end
for
文に取り出し変数を与えて繰り返しfor x in a puts x end
実行結果はいずれも以下のようになる。
9 6 4 3 2
each_with_index
, whileループ
添字が0から始まることに注意する。
each_with_index
メソッドで要素と添字を入れる変数を指定して繰り返しa.each_with_index do |x, i| printf("第%d要素(%d番目)は %d です。\n", i, i+1, x) end
while
文で繰り返し添字を表す補助変数を利用して、添字0から配列の個数より
1小さい数まで繰り返す。配列のlength
メソッドで個数を調べる。
i = 0 # ループ用補助変数で他と衝突しなければなんでもよい while i < a.length # a.lengthは配列aの要素数 (後述) printf("第%d要素(%d番目)は %d です。\n", i, i+1, a[i]) i += 1 # 補助変数 i の値を1増やす end
実行結果はいずれも以下のようになる。
第0要素(1番目)は 9 です。 第1要素(2番目)は 6 です。 第2要素(3番目)は 4 です。 第3要素(4番目)は 3 です。 第4要素(5番目)は 2 です。
配列に対して行なえる、次のメソッドを覚えておこう。
length
配列の長さを返す。たとえば、
x = [1, 2, "foo"]
であれば、x.length
は 3 となる。
size
配列の長さを返す。length
メソッドと同じ。
shift
配列の先頭の要素を取り除いた上で、取り除かれた要素の値を返す。 たとえば、
y = ["1", "abc", "bar"]
であれば、y.shift
は "1" となる。さらに、先頭が取
り除かれて y
自体は ["abc", "bar"]
とな
る。
sort
配列の要素を小さい順に並べ換えた結果を返す。たとえ ば、
z = [7, 5, 1, 22]
ならば、z.sort
は
[1, 5, 7, 22]
となる。並べ換えた結果をあとで利用したい場合は、 別の変数に代入する。
y = z.sort
sort
を、文字列を要素に含む配列に使うと、
辞書順に並べ換えた結果を返す。
meibo = ["やまだたろう", "なかまちたろう", "いいもりはなこ", "あいたあきら"]
ならば、meibo.sort
は、
["あいたあきら", "いいもりはなこ", "なかまちたろう", "やまだたろう"]
となる。なお、sort
は、元の配列のコピーを取ってか
ら並べ換え作業をするので、meibo.sort
としても、
meibo
変数の値は変わらない。meibo
変数の
値そのものの順番を壊して並べ換えたいときは
meibo.sort!
とする。元の値を直接操作することを破壊的操作という。
reverse
配列の要素の順序を逆にした配列を返す。たとえば、
y = [1, 5, 7, 22]
なら、y.reverse
は、
[22, 7, 5, 1]
となる。
sort, reverse
を組み合わせると、逆順に並べ換えた結
果が得られる。
meibo = ["やまだたろう", "なかまちたろう", "いいもりはなこ", "あいたあきら"]
のとき、
meibo.sort.reverse
=> ["やまだたろう", "なかまちたろう", "いいもりはなこ",
"あいたあきら"]
となる。
reverse
もsort
同様、元の変数の
値は変わらない。変えたい場合は、reverse!
メソッドを使う。