Edited at

Ruby on Railsで拡張されているEnumerableのメソッドまとめ

More than 3 years have passed since last update.

RailsではEnumerableモジュールを拡張しています

そこで、Rails 4.2.3で定義されているメソッドをすべて紹介してみたいと思います。


exclude?

各要素に引数で渡された値が含まれているか確認し、 含まれていない場合はtrue を返します。

rubyのEnumerableに定義されているinclude?の反対ですね。

[1, 2, 3].exclude?(5)

# => true
[1, 2, 3].exclude?(3)
# => false


index_by

ActiveRecordとかで取得したオブジェクトの配列を 特定のキーのハッシュに変換 します。

例えばCarsテーブルがあったとして、

id
maker
name
price

1
トヨタ
プリウス
1000000

2
アルファロメオ
166
3000000

3
フォルクスワーゲン
ゴルフ
1500000

4
トヨタ
ハリアー
2000000

普通に取得するとオブジェクトの配列が返ってきますが、

Car.find(:all)

# => [#<Car id: 1, maker: "トヨタ", name: "プリウス", price: 1000000>,#<Car id: 2, maker: "アルファロメオ", name: "166", price: 3000000>,...]

index_byを利用すると、

Car.find(:all).index_by(&:id)

# => {1=>#<Car id: 1, maker: "トヨタ", name: "プリウス", price: 1000000>,2=>#<Car id: 2, maker: "アルファロメオ", name: "166", price: 3000000>,...}

こんな感じでidをキーにしたハッシュ形式にしてくれます。

ちなみにキーが重複している場合は一つにまとめられてしまうので注意してください。


many?

{}ブロック内にある式の結果を満たす要素が 2つ以上ある場合にtrue を返します。

ちなみに、1つ以上ある場合を求めたい場合はany?を使えばいいです。

[1, 2, 3, 4, 5].many? { |n| n < 3 }

# => true
[1, 2, 3, 4, 5].many? { |n| n < 2 }
# => false
[1, 2, 3, 4, 5].any? { |n| n < 2 }
# => true

先ほどのCarsテーブルの例で言うとこんな感じ。

Car.find(:all).many? { |c| c.price <= 1500000 }

# => true
Car.find(:all).many? { |c| c.price <= 1000000 }
# => false
Car.find(:all).any? { |c| c.price <= 1000000 }
# => true


sum

各要素内の合計を返します。

[1, 2, 3].sum

# => 6
['foo', 'bar'].sum
# => "foobar"
[[1, 2], [2, 5]].sum
# => [1, 2, 2, 5]

先ほどのCarsテーブルの例で、priceの合計を求めたいならこう。

Car.find(:all).sum(&:price)

# => 7500000

# こういう風にも書ける
Car.find(:all).sum { |c| c.price }
# => 7500000

sumはinjectを使って合計を求める場合のショートカットとして作られたみたいです。

# injectと同じく、引数として初期値を与えれる

Car.find(:all).sum(0) { |c| c.price }
# => 7500000

# injectを使って同じことを書くとこんな感じになる
Car.find(:all).inject(0) { |sum, c| sum + c.price }
# => 7500000


参考

rubyで定義されているEnumerableモジュールもまとめているので、そちらもどうぞー。

selectなどの配列の抽出・検索を行うメソッドまとめ

mapなどの配列の値を操作するメソッドまとめ