From: Andrew Wagner on 1 Aug 2010 18:45 [Note: parts of this message were removed to make it a legal post.] How can I get a lazy array in Ruby? E.g., in Haskell, I can talk about [1..], which is an infinite list, lazily generated as needed. I can also do things like "iterate (+2) 0", which applies whatever function I give it to generate a lazy list. In this case, it would give me all even numbers. Anyway, I'm sure I can do such things in Ruby, but can't seem to work out how.
From: skim on 1 Aug 2010 22:56 [Note: parts of this message were removed to make it a legal post.] Ruby Arrays dynamically expand as needed. You can apply blocks to them to return things like even numbers. array = [] array.size # => 0 array[0] # => nil array[9999] # => nil array << 1 array.size # => 1 array << 2 << 3 << 4 array.size # => 4 array = (0..9).to_a array.select do |e| e % 2 == 0 end # => [0,2,4,6,8] Does this help? On Sun, Aug 1, 2010 at 17:45, Andrew Wagner <wagner.andrew(a)gmail.com> wrote: > How can I get a lazy array in Ruby? E.g., in Haskell, I can talk about > [1..], which is an infinite list, lazily generated as needed. I can also do > things like "iterate (+2) 0", which applies whatever function I give it to > generate a lazy list. In this case, it would give me all even numbers. > Anyway, I'm sure I can do such things in Ruby, but can't seem to work out > how. >
From: jeremy Ruten on 1 Aug 2010 23:22 Ruby 1.9 has the Enumerator class, which can act like a lazy list I think. A good example is given in the documentation: fib = Enumerator.new { |y| a = b = 1 loop { y << a a, b = b, a + b } } p fib.take(10) #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] Also, this is a nice trick: Infinity = 1.0/0 range = 5..Infinity p range.take(10) #=> [5, 6, 7, 8, 9, 10, 11, 12, 13, 14] This one only works for consecutive values though. jeremy On Sun, Aug 1, 2010 at 8:56 PM, skim <skim.la(a)gmail.com> wrote: > Ruby Arrays dynamically expand as needed. You can apply blocks to them to > return things like even numbers. > > array = [] > array.size # => 0 > array[0] # => nil > array[9999] # => nil > array << 1 > array.size # => 1 > array << 2 << 3 << 4 > array.size # => 4 > > array = (0..9).to_a > array.select do |e| > e % 2 == 0 > end > > # => [0,2,4,6,8] > > Does this help? > > On Sun, Aug 1, 2010 at 17:45, Andrew Wagner <wagner.andrew(a)gmail.com> wrote: > >> How can I get a lazy array in Ruby? E.g., in Haskell, I can talk about >> [1..], which is an infinite list, lazily generated as needed. I can also do >> things like "iterate (+2) 0", which applies whatever function I give it to >> generate a lazy list. In this case, it would give me all even numbers. >> Anyway, I'm sure I can do such things in Ruby, but can't seem to work out >> how. >> >
From: Benoit Daloze on 2 Aug 2010 03:02 On 2 August 2010 05:22, jeremy Ruten <jeremy.ruten(a)gmail.com> wrote: > Ruby 1.9 has the Enumerator class, which can act like a lazy list I > think. A good example is given in the documentation: > > fib = Enumerator.new { |y| > a = b = 1 > loop { > y << a > a, b = b, a + b > } > } > > p fib.take(10) #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] > > Also, this is a nice trick: > > Infinity = 1.0/0 > > range = 5..Infinity > p range.take(10) #=> [5, 6, 7, 8, 9, 10, 11, 12, 13, 14] > > This one only works for consecutive values though. > > jeremy > > On Sun, Aug 1, 2010 at 8:56 PM, skim <skim.la(a)gmail.com> wrote: >> Ruby Arrays dynamically expand as needed. You can apply blocks to them to >> return things like even numbers. >> >> array = [] >> array.size # => 0 >> array[0] # => nil >> array[9999] # => nil >> array << 1 >> array.size # => 1 >> array << 2 << 3 << 4 >> array.size # => 4 >> >> array = (0..9).to_a >> array.select do |e| >> e % 2 == 0 >> end >> >> # => [0,2,4,6,8] >> >> Does this help? >> >> On Sun, Aug 1, 2010 at 17:45, Andrew Wagner <wagner.andrew(a)gmail.com> wrote: >> >>> How can I get a lazy array in Ruby? E.g., in Haskell, I can talk about >>> [1..], which is an infinite list, lazily generated as needed. I can also do >>> things like "iterate (+2) 0", which applies whatever function I give it to >>> generate a lazy list. In this case, it would give me all even numbers. >>> Anyway, I'm sure I can do such things in Ruby, but can't seem to work out >>> how. >>> >> > So, with Enumerator it should be: even = Enumerator.new { |y| i = 0 loop { y << i i += 2 } } p even.take(5) # => [0, 2, 4, 6, 8] But that is not really common practice in Ruby (Enumerator for so simple things). You would probably need something like (0..max).step(2) { |even_n| p even_n } B.D.
From: Brian Candler on 2 Aug 2010 05:29 Benoit Daloze wrote: > So, with Enumerator it should be: > > even = Enumerator.new { |y| > i = 0 > loop { > y << i > i += 2 > } > } > > p even.take(5) # => [0, 2, 4, 6, 8] > > But that is not really common practice in Ruby (Enumerator for so > simple things). In any case, that Enumerator block form is only syntactic sugar. You can do the same without using the Enumerator class: even = Object.new def even.each(&blk) (2..1.0/0).step(2,&blk) end even.extend Enumerable p even.take(5) In both cases, all you're doing is having 'each' generate an infinite series, and then truncating it with 'take'. This is not useful normally, because you can't chain it - most of the Enumerable functions like 'map', 'select' etc collect the full results into an Array before continuing. However, it's quite possible to have these functions process one element at a time without generating the intermediate arrays, and there is an implementation of this in the 'facets' library: >> RUBY_VERSION => "1.8.6" >> require 'rubygems' => true >> require 'facets/enumerator' => true >> require 'facets/enumerable/defer' => true >> (1..1_000_000_000).defer.select { |i| i % 2 == 0 }.map { |i| i+100 }.take(10).to_a => [102, 104, 106, 108, 110, 112, 114, 116, 118, 120] Infinite lists are no problem here - each element propagates through the whole chain before the next. You're processing 'horizontally' rather than 'vertically'. Note that this doesn't use Threads or Fibers, it's efficient, and it works in ruby 1.8. For the implementation details, see the Denumerator class. -- Posted via http://www.ruby-forum.com/.
|
Next
|
Last
Pages: 1 2 Prev: [ANN] RubyConf registration and Call For Proposals now open! Next: Ruby 1.9 |