aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Keys <adam@therealadam.com>2008-09-03 16:20:25 +0200
committerMichael Koziarski <michael@koziarski.com>2008-09-03 16:21:53 +0200
commit10fe6a6d8940300dd6698ec38e9c9573404e687d (patch)
tree3b6867dd80f7b7fe28f2f5c683d2844de51138d0
parentb36d000975824518d64bcdbd731287c25e9af604 (diff)
downloadrails-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]
-rw-r--r--activesupport/lib/active_support/core_ext/enumerable.rb22
-rw-r--r--activesupport/test/core_ext/enumerable_test.rb5
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] },