2

I have a method that returns a hash. I want to repeat through this method five times, collecting the results into an array. Right now, I'm trying it like this:

votes = 5.times.collect{ create_vote }.inject{|memo, vote| memo << vote}

This doesn't work, and I believe it's failing because memo isn't an array. Is there another approach I could take to this problem?

4 Answers 4

5

Yes:

votes = 5.times.collect { create_vote }

More generally, use each_with_object:

votes = 5.times.collect { create_vote }.each_with_object([]) {|o,memo| memo << o }

each_with_object is a method added because Ruby Core found that using inject in the way you intended to use it was very common.

Sign up to request clarification or add additional context in comments.

2 Comments

inject([]){|memo, vote| memo << vote} is fine (because memo<<vote returns memo). But when memo is a hash and you do something like memo[vote]=true in the block, it stops working (because it returns true, not memo). That's when each_with_object comes in handy.
Indeed, but your intentions are clearer if you use the right method.
3

Use #map on a range instead of #times on a fixnum

(0..5).map { create_vote }

Or, map an array from the times

5.times.map { create_vote }

Each will give you an array with 5 elements.

Comments

1

How about:

votes = (1..5).collect { create_vote }

Comments

0

I tried using the accepted answer, but then Rubocop told me that it would be faster to use Array.new as in:

votes = Array.new(5) { create_vote }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.