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などの配列の値を操作するメソッドまとめ