Implement the accumulate
operation, which, given a collection and an
operation to perform on each element of the collection, returns a new
collection containing the result of applying that operation to each element of
the input collection.
Given the collection of numbers:
And the operation:
x => x * x
)Your code should be able to produce the collection of squares:
Check out the test suite to see the expected function signature.
Keep your hands off that collect/map/fmap/whatchamacallit functionality provided by your standard library! Solve this one yourself using other basic tools instead.
It is typical to call #to_enum when defining methods for a generic Enumerable, in case no block is passed.
Here is an additional test you could add:
def test_accumulate_when_block_is_deferred
skip
accumulate_enumerator = [1, 2, 3].accumulate
accumulated_result = accumulate_enumerator.map do |number|
number * number
end
assert_equal [1, 4, 9], accumulated_result
end
For installation and learning resources, refer to the Ruby resources page.
For running the tests provided, you will need the Minitest gem. Open a terminal window and run the following command to install minitest:
gem install minitest
If you would like color output, you can require 'minitest/pride'
in
the test file, or note the alternative instruction, below, for running
the test file.
Run the tests from the exercise directory using the following command:
ruby accumulate_test.rb
To include color from the command line:
ruby -r minitest/pride accumulate_test.rb
Conversation with James Edward Gray II https://twitter.com/jeg2
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
require 'minitest/autorun'
require_relative 'accumulate'
class ArrayTest < Minitest::Test
def test_empty_accumulation
assert_equal [], [].accumulate { |e| e * e }
end
def test_accumulate_squares
skip
result = [1, 2, 3].accumulate do |number|
number * number
end
assert_equal [1, 4, 9], result
end
def test_accumulate_upcases
skip
result = %w(hello world).accumulate(&:upcase)
assert_equal %w(HELLO WORLD), result
end
def test_accumulate_reversed_strings
skip
result = %w(the quick brown fox etc).accumulate(&:reverse)
assert_equal %w(eht kciuq nworb xof cte), result
end
def test_accumulate_recursively
skip
result = %w(a b c).accumulate do |char|
%w(1 2 3).accumulate do |digit|
"#{char}#{digit}"
end
end
assert_equal [%w(a1 a2 a3), %w(b1 b2 b3), %w(c1 c2 c3)], result
end
def test_do_not_change_in_place
skip
original = [1, 2, 3]
copy = original.dup
original.accumulate { |n| n * n }
assert_equal copy, original
end
end
class Array
def accumulate
return to_enum unless block_given?
each_with_object([]) {|element, result| result << yield(element)}
end
end
require 'minitest/autorun'
require_relative 'accumulate'
class ArrayTest < Minitest::Test
def test_empty_accumulation
# skip
assert_equal [], [].accumulate { |e| e * e }
end
def test_accumulate_squares
# skip
result = [1, 2, 3].accumulate do |number|
number * number
end
assert_equal [1, 4, 9], result
end
def test_accumulate_upcases
# skip
result = %w(hello world).accumulate(&:upcase)
assert_equal %w(HELLO WORLD), result
end
def test_accumulate_reversed_strings
# skip
result = %w(the quick brown fox etc).accumulate(&:reverse)
assert_equal %w(eht kciuq nworb xof cte), result
end
def test_accumulate_recursively
# skip
result = %w(a b c).accumulate do |char|
%w(1 2 3).accumulate do |digit|
"#{char}#{digit}"
end
end
assert_equal [%w(a1 a2 a3), %w(b1 b2 b3), %w(c1 c2 c3)], result
end
def test_do_not_change_in_place
# skip
original = [1, 2, 3]
copy = original.dup
original.accumulate { |n| n * n }
assert_equal copy, original
end
def test_accumulate_when_block_is_deferred
# skip
accumulate_enumerator = [1, 2, 3].accumulate
accumulated_result = accumulate_enumerator.map do |number|
number * number
end
assert_equal [1, 4, 9], accumulated_result
end
end
A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.
Here are some questions to help you reflect on this solution and learn the most from it.
Level up your programming skills with 3,450 exercises across 52 languages, and insightful discussion with our volunteer team of welcoming mentors. Exercism is 100% free forever.
Sign up Learn More
Community comments
This was a great problem for understanding the inner workings of Ruby.