diff options
author | Adam Keys <adam@therealadam.com> | 2008-09-03 16:20:25 +0200 |
---|---|---|
committer | Michael Koziarski <michael@koziarski.com> | 2008-09-03 16:21:53 +0200 |
commit | 10fe6a6d8940300dd6698ec38e9c9573404e687d (patch) | |
tree | 3b6867dd80f7b7fe28f2f5c683d2844de51138d0 /activesupport | |
parent | b36d000975824518d64bcdbd731287c25e9af604 (diff) | |
download | rails-10fe6a6d8940300dd6698ec38e9c9573404e687d.tar.gz rails-10fe6a6d8940300dd6698ec38e9c9573404e687d.tar.bz2 rails-10fe6a6d8940300dd6698ec38e9c9573404e687d.zip |
Add each_with_object from 1.9 for a more convenient alternative to inject.
Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#962 state:committed]
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/lib/active_support/core_ext/enumerable.rb | 22 | ||||
-rw-r--r-- | activesupport/test/core_ext/enumerable_test.rb | 5 |
2 files changed, 26 insertions, 1 deletions
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index e451e9933a..fd94bc051f 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -64,8 +64,28 @@ module Enumerable end end + # Iterates over a collection, passing the current element *and* the + # +memo+ to the block. Handy for building up hashes or + # reducing collections down to one object. Examples: + # + # %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } #=> {'foo' => 'FOO', 'bar' => 'BAR'} + # + # *Note* that you can't use immutable objects like numbers, true or false as + # the memo. You would think the following returns 120, but since the memo is + # never changed, it does not. + # + # (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1 + # + def each_with_object(memo, &block) + returning memo do |memo| + each do |element| + block.call(element, memo) + end + end + end unless [].respond_to?(:each_with_object) + # Convert an enumerable to a hash. Examples: - # + # # people.index_by(&:login) # => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...} # people.index_by { |person| "#{person.first_name} #{person.last_name}" } diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb index 2315d8f3db..deb9b7544d 100644 --- a/activesupport/test/core_ext/enumerable_test.rb +++ b/activesupport/test/core_ext/enumerable_test.rb @@ -58,6 +58,11 @@ class EnumerableTests < Test::Unit::TestCase assert_equal Payment.new(0), [].sum(Payment.new(0)) end + def test_each_with_object + result = %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } + assert_equal({'foo' => 'FOO', 'bar' => 'BAR'}, result) + end + def test_index_by payments = [ Payment.new(5), Payment.new(15), Payment.new(10) ] assert_equal({ 5 => payments[0], 15 => payments[1], 10 => payments[2] }, |