Reputation: 823
I'm trying to use a while
loop inside #inject
. However, the last memo becomes nil at some point and I don't understand why. Here is my example (I use #each
on the example just to show the expected result):
class TestClass
BASE_ARRAY = [5, 1]
def test_method(value)
result = []
BASE_ARRAY.each do |item|
while item <= value
result << item
value -= item
end
end
result
end
def test_method_alternate(value)
BASE_ARRAY.inject do |memo, item|
while item <= value
p memo
# memo << item (if left, returns NoMethodError for nil Class)
value -= item
end
end
end
end
solution_one = TestClass.new.test_method(11)
p solution_one # => [5, 5, 1]
solution_two = TestClass.new.test_method_alternate(11)
p solution_two
# => []
[]
nil
How does the accumulator become nil
?
Upvotes: 0
Views: 225
Reputation: 123553
You're getting nil
initially from the while
loop:
The result of a
while
loop isnil
unlessbreak
is used to supply a value.
That result becomes the result of other statements in a chain:
while
-> do |memo, item|
-> BASE_ARRAY.inject
-> test_method_alternate(11)
-> solution_two
To have .inject
fill up an array, you'll want to provide an empty array to use as the first memo
:
BASE_ARRAY.inject([]) do |memo, item|
# ... ^^^^
Then, be sure the array is the result of the block:
... do |memo, item|
while item <= value
memo << item
value -= item
end
memo # <---
end
Upvotes: 1
Reputation: 16793
Two things:
memo
with a value, in this case, you'll want a []
.memo
on each iteration of inject
.So, you should get your desired result of [5, 5, 1]
by changing your method to be like this:
def test_method_alternate(value)
BASE_ARRAY.inject([]) do |memo, item|
while item <= value
memo << item
value -= item
end
memo
end
end
Upvotes: 1