Enumerable

繰り返しを行なうクラスのための Mix-in。このモジュールの メソッドは全て each を用いて定義されているので、インクルード するクラスには each が定義されていなければなりません。

メソッド:

all? {|item| ... } ((<ruby 1.7 feature>))

各要素に対してブロックを評価し、すべての結果が真である場合に true を返します。ブロックが偽を返した時点で、ただちに false を返します。

p [1,2,3].all? {|v| v > 0}   # => true
p [1,2,3].all? {|v| v > 1}   # => false
any? {|item| ... } ((<ruby 1.7 feature>))

各要素に対してブロックを評価し、すべての結果が偽である場合に false を返します。ブロックが真を返した時点で、ただちに true を返します。

p [1,2,3].any? {|v| v > 3}   # => false
p [1,2,3].any? {|v| v > 1}   # => true
collect {|item| ... }
map {|item| ... }

各要素に対してブロックを評価した結果を全て含む配列を返します。

ブロックを省略した場合、

obj.collect {|item| item}

を行います。これは Enumerable#to_a と同じで す。

each_with_index {|item,index| ... }

要素とインデックスを両方与えるイテレータ。

self を返します。

find([ifnone]) {|item| ... }
detect([ifnone]) {|item| ... }

要素に対してブロックを評価した値が真になった最初の要素を返します。 真になる要素がひとつも見つからなかったときは ifnone を(もし 指定されていれば)評価して nil を返します。

ifnone には文字列かあるいは、call メソッドを持つオブジェ クト(例えば Proc)を指定します。

[1,2,3].find("raise") {|v| v > 4}
# => -:1: unhandled exception

ruby 1.7 feature: ifnone に文字列は指定できなくなりました。

find_all {|item| ... }
select {|item| ... }

各要素に対してブロックを評価した値が真であった要素を全て含む配列を 返します。真になる要素がひとつもなかった場合は空の配列を返します。

grep(pattern)
grep(pattern) {|item| ... }

pattern === item が成立する要素を全て含んだ配列を返し ます。ブロックとともに呼び出された時には条件の成立した要素に対して それぞれブロックを評価し、その結果の配列を返します。マッチする要素 がひとつもなかった場合は空の配列を返します。

inject([init]) {|result, item| ... } ((<ruby 1.7 feature>))

最初に初期値 initself の最初の要素を引数にブロック を実行します。2 回目以降のループでは、前のブロックの実行結果と self の次の要素を引数に順次ブロックを実行します。そうして最 後の要素まで繰り返し、最後のブロックの実行結果を返します。

要素が空の場合は init を返します。

初期値 init を省略した場合は、最初に先頭の要素と 2 番目の要 素をブロックに渡します。この場合、要素が 1 つしかなければブロック を実行せずに最初の要素を返します。要素が空なら nil を返しま す。

合計の計算

p [1,2,3,4,5].inject(0) {|result, item| result + item }
  => 15

これは以下のように書くのと同じです。

result = 0
[1,2,3,4,5].each {|v| result += v }
p result
=> 15
member?(val)
include?(val)

val== の関係にある要素を含むとき真を返します。

max

最大の要素を返します。全要素が互いに <=> メソッドで比較でき ることを仮定しています。

max {|a, b| ... }

ブロックの評価値を元に各要素を比較し、最大の要素を返します。

ブロックの値は、a>b のとき正、a==b のとき 0、a<b のとき負の整数を、期待しています。ブロックが整数以外を返したときは 例外 TypeError が発生します。

min

最小の要素を返します。全要素が互いに <=> メソッドで比較でき ることを仮定しています。

min {|a, b| ... }

ブロックの評価値で各要素を比較し、最小の要素を返します。

ブロックの値は、a>b のとき正、a==b のとき 0、a<b のとき負の整数を、期待しています。ブロックが整数以外を返したときは 例外 TypeError が発生します。

partition {|item| ... } ((<ruby 1.7 feature>))

各要素に対してブロックを評価した値が真であった要素からなる配列と 偽であった要素からなる配列からなる配列を返します。

[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0].partition { |i| i % 3 == 0 }
 #=> [[9, 6, 3, 0], [10, 8, 7, 5, 4, 2, 1]]
reject {|item| ... }

各要素に対してブロックを評価し、その値が偽であった要素を集めた新し い配列を返します。

sort
sort {|a, b| ... }

全ての要素を昇順にソートした配列を生成して返します。

ブロックなしのときは <=> メソッドを要素に対して呼び、その結 果をもとにソートします。

<=> 以外でソートしたい場合は、ブロックを指定します。この場合 ブロックの評価結果を元にソートします。ブロックの値は、a>b の とき正、a==b のとき 0、a<b のとき負の整数を、期待して います。ブロックが整数以外を返したときは例外 TypeError が発 生します。

sort_by {|item| ... } ((<ruby 1.7 feature>))

ブロックの評価結果を <=> メソッドで比較して昇順にソートを行 い、その結果を新しく生成した配列で返します。これは、以下とほぼ同じ 動作をします。

def sort_by
  self.collect {|i| [yield(i), i]}.
     sort {|a,b| a[0] <=> b[0]}.
     collect! {|i| i[1]}
end

sort_by を使わない以下の例では、比較を行う度に downcase が実 行されるため、downcase の実行速度が遅ければ sort の速度が致命的に 遅くなります。

p ["BAR", "FOO", "bar", "foo"].sort {|a,b| a.downcase <=> b.downcase }

sort_by を使えば downcase の実行回数は要素数です(つまり、そ の部分は O(n) のオーダー)。

p ["BAR", "FOO", "bar", "foo"].sort_by {|v| v.downcase}
=> ruby 1.7.1 (2001-08-24) [i586-linux]
   ["BAR", "bar", "FOO", "foo"]

以下の、実行回数の検証結果を参照してみてください。

class Integer
  def count
    $n += 1
    self
  end
end

ary = []
1.upto(1000) {|v| ary << rand(v)}

$n = 0
ary.sort {|a,b| a.count <=> b.count }
p $n          # => 18200

$n = 0
ary.sort_by {|v| v.count}
p $n          # => 1000

Enumerable#sort のソートアルゴリズムは安定(stable) ではありませんが(比較結果が同じ要素に対して、元の順序を保持しないこ とを「安定ではない」と言います)、sort_by を使って以下のようにするこ とで stable sort を実現できます。

i = 0
ary.sort_by {|v| [v, i += 1]}
to_a
entries

全ての要素を含む配列を返します。