9

I know of Python's list method that can consume all elements from a generator. Is there something like that available in Ruby?

I know of :

elements = []
enumerable.each {|i| elements << i}

I also know of the inject alternative. Is there some ready available method?

Geo
  • 93,257
  • 117
  • 344
  • 520

2 Answers2

20

Enumerable#to_a

sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • 1
    Ruby 2.0 introduce `Enumerator::Lazy` that has `#to_a` and `#force` (for the same purpose). You can read more here [Ruby 2.0 Enumerable::Lazy](http://railsware.com/blog/2012/03/13/ruby-2-0-enumerablelazy/) – gregolsen Sep 22 '12 at 06:26
4

If you want to do some transformation on all the elements in your enumerable, the #collect (a.k.a. #map) method would be helpful:

elements = enumerable.collect { |item| item.to_s }

In this example, elements will contain all the elements that are in enumerable, but with each of them translated to a string. E.g.

enumerable = [1, 2, 3]
elements = enumerable.collect { |number| number.to_s }

In this case, elements would be ['1', '2', '3'].

Here is some output from irb illustrating the difference between each and collect:

irb(main):001:0> enumerable = [1, 2, 3]
=> [1, 2, 3]
irb(main):002:0> elements = enumerable.each { |number| number.to_s }
=> [1, 2, 3]
irb(main):003:0> elements
=> [1, 2, 3]
irb(main):004:0> elements = enumerable.collect { |number| number.to_s }
=> ["1", "2", "3"]
irb(main):005:0> elements
=> ["1", "2", "3"]
Sarah Vessels
  • 30,930
  • 33
  • 155
  • 222
  • Nothing would prevent me from doing that in `each`. – Geo Sep 09 '09 at 15:48
  • Geo: the difference between `each` and `collect` is that `each` does not return an array, whereas `collect` does. Hence if you substituted `each` for `collect` in my last example, `elements` would be the original array of numbers (i.e. the same as `enumerable`), _not_ an array of numeric strings (i.e. what you would get by using `collect`). – Sarah Vessels Sep 09 '09 at 18:45
  • I wasn't referring to the case you mentioned. `elements.each {|e| list << e.to_s }` does the same thing. I find it's just a matter of personal taste which method you're using. – Geo Sep 09 '09 at 19:12
  • 1
    Geo: that's true about personal taste, but something can be said for how, with `collect`, you can initialize and populate an array in one step, whereas with `each` you must initialize an array beforehand. – Sarah Vessels Sep 09 '09 at 19:20
  • @Tempus sometimes there is a difference. Try `a=[];b=1.upto(5).collect{|i|a< – yurisich Jul 22 '13 at 19:29