Rubyでは、配列は順序を持ち、整数のインデックスで要素を指定できる、あらゆるオブジェクトのコレクションです。
配列のインデックスは0から始まります。
負のインデックスは、配列の末尾からの位置を表します。たとえば、-1は配列の最後の要素、-2は後ろから2番目の要素を指し、以下同様に続きます。
配列は通常、[]という記法で作成します。
どんな型のオブジェクトでも入れることができます。
array = [1, "two", 3.0]
配列の要素は、#[]メソッドを使ってインデックスで取得できます。
これは、そのインデックスにある要素を返すか、開始インデックスから指定した長さだけ続く部分配列を返します。
負のインデックスは、配列の末尾からさかのぼって数えます。
a = [ "a", "b", "c", "d", "e" ]
a[2] #=> "c"
a[6] #=> nil
a[1, 3] #=> [ "b", "c", "d" ]
a[-1] #=> "e"
a[-2] #=> "d"
a[-3, 2] #=> ["c", "d"]
配列には便利なメソッドがたくさんあります。 よく使うものをいくつか紹介します。
fibonacci = [0, 1, 1, 2, 3, 5, 8, 13]
fibonacci.size #=> 8
fibonacci.sum #=> 33
fibonacci.reverse #=> [13, 8, 5, 3, 2, 1, 1, 0]
Rubyでは、コレクションを繰り返し処理するためにループを使うのではなく、列挙を使います。
列挙とは、コレクション(ここでは配列)を順に見ていき、各要素に対して何らかの操作を行うことです。列挙はRubyの重要な概念で、並べ替え、グループ化、マッピング、畳み込みなど、さまざまな場面で使われます。
配列の各単語を出力する列挙は、次のようになります。
words = ["the", "cat", "sat"]
words.each do |word|
puts word
end
# Output:
# the
# cat
# sat
この例では、配列に対して.eachメソッドを呼び出し、1つの入力(word)を受け取ってそれを出力する_ブロック_を渡しています。
_ブロック_については、このトラックの後半で詳しく見ていきますが、今のところは、0個以上の入力を受け取ることができる名前のない関数だと考えておけば大丈夫です。
ブロックは、do...endの構文(上記)でも、{}の構文(下記)でも定義できます。
ブロックを使う配列のメソッドの例を、ほかにもいくつか挙げます。
fibonacci = [0, 1, 1, 2, 3, 5, 8, 13]
fibonacci.count { |number| number == 1 } #=> 2
fibonacci.any? { |number| number == 6 } #=> false
fibonacci.select { |number| number.odd? } #=> [1, 1, 3, 5, 13]
fibonacci.all? { |number| number < 20 } #=> true
fibonacci.map { |number| number * 2 } #=> [0, 2, 2, 4, 6, 10, 16, 26]
この演習では、熱心なバードウォッチャーとして、過去7日間に庭に何羽の鳥が訪れたかを記録します。庭に訪れた鳥の数に関する、5つのタスクに取り組みます。
比較のため、先週の記録をいつも手元に控えてあります。先週の記録は、0、2、5、3、7、8、4でした。先週の記録を返すBirdCount.last_weekメソッドを実装しましょう。
BirdCount.last_week
# => [0, 2, 5, 3, 7, 8, 4]
昨日庭に訪れた鳥の数を返すBirdCount#yesterdayメソッドを実装しましょう。鳥の数は日付順に並んでいて、最初の要素が最も古い日の数、最後の要素が今日の数です。
birds_per_day = [2, 5, 0, 7, 4, 1]
bird_count = BirdCount.new(birds_per_day)
bird_count.yesterday
# => 4
庭に訪れた鳥の合計数を返すBirdCount#totalメソッドを実装しましょう。
birds_per_day = [2, 5, 0, 7, 4, 1]
bird_count = BirdCount.new(birds_per_day)
bird_count.total
# => 19
日によって、鳥が多く訪れる日もあれば少ない日もあります。忙しい日とは、庭に5羽以上の鳥が訪れた日のことです。
忙しい日の数を返すBirdCount#busy_daysメソッドを実装しましょう。
birds_per_day = [2, 5, 0, 7, 4, 1]
bird_count = BirdCount.new(birds_per_day)
bird_count.busy_days
# => 2
庭に鳥が1羽も訪れなかった日があればtrueを、そうでなければfalseを返すBirdCount#day_without_birds?メソッドを実装しましょう。
birds_per_day = [2, 5, 0, 7, 4, 1]
bird_count = BirdCount.new(birds_per_day)
bird_count.day_without_birds?
# => true