Enumerable

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

メソッド:

all?
all? {|item| ... }

ruby 1.7 feature:

すべての要素が真である場合に true を返します。偽である要素が あれば、ただちに false を返します。

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

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

ruby 1.7 feature:

すべての要素が偽である場合に false を返します。真である要素 があれば、ただちに true を返します。

ruby 1.8 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 を返します。 (ruby 1.7 feature: ifnoneを評価した結果を返します。 *1) *2

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

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

要素が存在しなければ nil を返します。

max {|a, b| ... }

ブロックの評価結果で各要素の大小判定を行い、最大の要素を返します。 要素が存在しなければ nil を返します。

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

max_by {|item| ... } ((<ruby 1.9 feature>))

ブロックの評価結果を <=> で比較し、最大の要素を返します。 要素が存在しなければ nil を返します。

max と max_by の違いは sort と sort_by の違いと同じです。詳細は sort_by を参照してください。

min

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

要素が存在しなければ nil を返します。

min {|a, b| ... }

ブロックの評価結果で各要素の大小判定を行い、最小の要素を返します。 要素が存在しなければ nil を返します。

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

min_by {|item| ... } ((<ruby 1.9 feature>))

ブロックの評価結果を <=> で比較し、最小の要素を返します。 要素が存在しなければ nil を返します。

min と min_by の違いは sort と sort_by の違いと同じです。詳細は sort_by を参照してください。

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 が発 生します。

Enumerable#sort は安定ではありません (unstable sort)。

註: 比較結果が同じ要素は元の順序通りに並ぶソートを 「安定なソート (stable sort)」と言います。

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

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

class Array
  def sort_by
    self.collect {|i| [yield(i), i] }.
       sort {|a,b| a[0] <=> b[0] }.
       collect! {|i| i[1]}
  end
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 }

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

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_by は安定ではありません (unstable sort)。

註: 比較結果が同じ要素は元の順序通りに並ぶソートを 「安定なソート (stable sort)」と言います。

なお、sort_by を以下のように使うと安定なソートを実装できます。

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

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

zip([ary1[, ary2[, ...]]])
zip([ary1[, ary2[, ...]]]) {|v1, v2, ...| ...}

ruby 1.7 feature:

self と引数に渡した配列の各要素からなる配列の配列を生成して 返します。生成される配列の要素数は self の要素数です。

p [1,2,3].zip([4,5,6], [7,8,9])
=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

p [1,2].zip([:a,:b,:c], [:A,:B,:C,:D])
=> [[1, :a, :A], [2, :b, :B]]

p (1..5).zip([:a,:b,:c], [:A,:B,:C,:D])
=> [[1, :a, :A], [2, :b, :B], [3, :c, :C], [4, nil, :D], [5, nil, nil]]

ブロック付きで呼び出された場合は、各配列を要素に渡してブロックを実 行します。この場合、zip は、常に nil を返します。

p [1,2,3].zip([4,5,6], [7,8,9]) {|ary|
  p ary
}
=> [1, 4, 7]
   [2, 5, 8]
   [3, 6, 9]
   nil

*11.7 featureかも。いつから?
*2あらい: ifnone に文字列が指定できなくなってから<URL:http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/enum.c.diff?r1=1.28&r2=1.29>みたい



rubyist ML