-
Description I needed to iterate a block on a value n times and return the value to solve a kata. Getting f(f(..f(x)..)) applying f n times. This is the trivial solution:
n.times do x = f.call(x) end return x
As times returns n rather than anything in the block a separate return x is needed after the block. Also x = modified x is needed. Wouldn't it be nice to have something built in for this purpose? like
x.modify(n, &block)
It turns out that we can achieve something pretty close to this with the built in
inject
. Astimes
without a block returns anEnumerator
, as mostEnumerable
functions do, (yielding increasing numbers), with the daisy chaining of Enumerables, using only the accumulator of inject this works fine:n.times.inject(x) { |x| block.call(x) }
However this doesn't work :( as inject in this case feeds in the index:
n.times.inject(x, &block)
Code class Object def modify(n) return to_enum :modify unless block_given? case n when Enumerator then n.each.inject(self) { |acc| yield(acc) } when Numeric then n.times.inject(self) { |acc| yield(acc) } end end end p 5.modify 2.times, &:~@ # flipping bits twice
Test Cases describe "Solution" do it "should test for something" do Test.assert_equals(3.times.inject('a') { |x| x * 2 }, 'aaaaaaaa', "duplicating 'a' 3 times") Test.assert_equals('a'.modify(3) { |x| x * 2 }, 'aaaaaaaa', "duplicating 'a' 3 times") Test.assert_equals(5.modify(2, &:~@), 5, 'flipping the bits twice returns the same') # and now the cool DSL bit : Test.assert_equals((5.modify 2.times, &:~@), 5, 'flipping the bits twice returns the same') end end
Output:
-
This comment has been hidden. You can view it now .
This comment can not be viewed.
- |
- Reply
- Edit
- View Solution
- Expand 1 Reply Expand {{ comments?.length }} replies
- Collapse
- Remove
- Remove comment & replies
- Report
Please sign in or sign up to leave a comment.