これまで使っていた変数には値を一つしか入れていなかったが、
複数の値をまとめて扱うこともできる。
複数の値をまとめて保持するものが配列である。
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 : (以下何個でも)
配列に格納されている要素は、一つ一つ取り出して利用する。 そのための方法として
while
ループで取り出すfor
または
each
メソッドでループを作成する。がある。変数 x
に配列が入っているとして、
1の場合は以下のようにする。
i = 0 # ループ用補助変数で他と衝突しなければなんでもよい
while i < x.length # 0 から 個数-1 まで繰り返す
……x[i] を利用したなんらかの処理……
i += 1 # 補助変数 i の値を1増やす
end
2はたとえば、配列から添字を介さず一つずつ取り出した要素を変数
j
に順次代入して処理を行なう処理は以下のようなものになる。
for j in x
……jを利用したなんらかの処理……
end
x.each do |j|
……jを利用したなんらかの処理……
end
どちらも同じ働きをする。仮に x=[3, 2, 1, 10]
だった場合、ループ内部は4回繰り返される。そのとき、
一回目: j=3 二回目: j=2 三回目: j=1 四回目: j=10
と順次値を変えながら繰り返すので、j
を計算に利用したりし
て処理を進める。
配列に対して行なえる、次のメソッドを覚えておこう。
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!
メソッドを使う。
次の四つのプログラムは、いずれも与えられた標準入力をいったん配列 に取り込み、そのまま出力するプログラムである。
#!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- n = 0 # 読み込むときの添字 contents = [] while line=gets contents[n] = line n += 1 end n = 0 # また0から始める while n < contents.length # 行数分だけくり返す print contents[n] n += 1 end
#!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- contents = [] # 読み込み while line = gets contents << line end # 出力 for line in contents print line end
#!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- contents = readlines contents.each do |line| print line end
#!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- print readlines
print
メソッドは、与えたものが配列の場合、各要素を先
頭から順に出力してくれる(ただ、この方法は簡単すぎて配列の使い方の練習に
はならない)。