root/trunk/activesupport/lib/active_support/core_ext/enumerable.rb
| Revision 9093, 1.8 kB (checked in by pratik, 5 months ago) |
|---|
| Line | |
|---|---|
| 1 | module Enumerable |
| 2 | # Collect an enumerable into sets, grouped by the result of a block. Useful, |
| 3 | # for example, for grouping records by date. |
| 4 | # |
| 5 | # Example: |
| 6 | # |
| 7 | # latest_transcripts.group_by(&:day).each do |day, transcripts| |
| 8 | # p "#{day} -> #{transcripts.map(&:class) * ', '}" |
| 9 | # end |
| 10 | # "2006-03-01 -> Transcript" |
| 11 | # "2006-02-28 -> Transcript" |
| 12 | # "2006-02-27 -> Transcript, Transcript" |
| 13 | # "2006-02-26 -> Transcript, Transcript" |
| 14 | # "2006-02-25 -> Transcript" |
| 15 | # "2006-02-24 -> Transcript, Transcript" |
| 16 | # "2006-02-23 -> Transcript" |
| 17 | def group_by |
| 18 | inject ActiveSupport::OrderedHash.new do |grouped, element| |
| 19 | (grouped[yield(element)] ||= []) << element |
| 20 | grouped |
| 21 | end |
| 22 | end if RUBY_VERSION < '1.9' |
| 23 | |
| 24 | # Calculates a sum from the elements. Examples: |
| 25 | # |
| 26 | # payments.sum { |p| p.price * p.tax_rate } |
| 27 | # payments.sum(&:price) |
| 28 | # |
| 29 | # This is instead of |
| 30 | # |
| 31 | # payments.inject { |sum, p| sum + p.price } |
| 32 | # |
| 33 | # Also calculates sums without the use of a block: |
| 34 | # |
| 35 | # [5, 15, 10].sum # => 30 |
| 36 | # |
| 37 | # The default identity (sum of an empty list) is zero. |
| 38 | # However, you can override this default: |
| 39 | # |
| 40 | # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0) |
| 41 | # |
| 42 | def sum(identity = 0, &block) |
| 43 | return identity unless size > 0 |
| 44 | |
| 45 | if block_given? |
| 46 | map(&block).sum |
| 47 | else |
| 48 | inject { |sum, element| sum + element } |
| 49 | end |
| 50 | end |
| 51 | |
| 52 | # Convert an enumerable to a hash. Examples: |
| 53 | # |
| 54 | # people.index_by(&:login) |
| 55 | # => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...} |
| 56 | # people.index_by { |person| "#{person.first_name} #{person.last_name}" } |
| 57 | # => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...} |
| 58 | # |
| 59 | def index_by |
| 60 | inject({}) do |accum, elem| |
| 61 | accum[yield(elem)] = elem |
| 62 | accum |
| 63 | end |
| 64 | end |
| 65 | end |
Note: See TracBrowser for help on using the browser.