繰り返しを行なうクラスのための Mix-in
。このモジュールの
メソッドは全て each
を用いて定義されているので、インクルード
するクラスには each
が定義されていなければなりません。
all?
all? {|item| ... }
すべての要素が真である場合に 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| ... }
すべての要素が偽である場合に 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>))
最初に初期値 init と self
の最初の要素を引数にブロック
を実行します。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, ...| ...}
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>みたい