seq
Defines a Seq class, which cycles over elements in an array.
s = Seq.new([1,2])
s.next #=> 1
s.next #=> 2
s.next #=> 1
# and so on forever
They can be constrained to only return n
items,
s = Seq.new([1,2,3], 2)
s.next #=> 1
s.next #=> 2
s.next #=> nil
s.next #=> nil
and can start from an offset.
s = Seq.new([1,2,3], 2, 1)
s.next #=> 2
s.next #=> 3
s.next #=> nil
s.next #=> nil
You can also provide a different default (as opposed to nil
).
list = %w(a b c d)
s = Seq.new(list, 3, 0, list.last)
s.next #=> a
s.next #=> b
s.next #=> c
s.next #=> d
s.next #=> d
Seq has #each
defined and includes the Enumerable
module so the usual stuff applies.
s = Seq.new([1,2,3,4], 10)
s.map {|i| i * 2 } #=> [2, 4, 6, 8, 2, 4, 6, 8, 2, 4]
s.next #=> nil
# Standard methods will increment the number of items that have been returned meaning
# you have to call #reset
s.reset
s.next #=> 1
# You can use special ! versions to avoid incrementing the number of cycles, but note
# this will start and finish based on the current index and items returned. So here
# we are on the second item in the original list, ie. "2".
s.map! {|i| i * 2 } #=> [4, 6, 8, 2, 4, 6, 8, 2, 4]
# Note this only returned 9 items as we had already called #next, and it started on 2
# which was mapped to 4.
s.reset
s.entries #=> [1, 2, 3, 4, 1, 2, 3, 4, 1, 2]
s.reject! {|i| i < 3 } #=> [3, 4, 3, 4]
s.take(4) #=> [1, 2, 3, 4]
s.entries #=> [1, 2, 3, 4, 1, 2]
s.reject! {|i| i < 3 } #=> [3, 4]
Seq::Random
A subclass of Seq which returns random elements.
require 'seq/random'
r = Seq::Random.new([1,2,3], 5)
r.entries #=> [2, 1, 1, 3, 2]
r.entries #=> [1, 3, 2, 3, 3]
Seq::Lazy
Lazily evaluates a block using starting list given.
require 'seq/lazy'
fibs = Seq::Lazy.new([1,1]) {|list| list[-1] + list[-2] }
fibs.take(10) #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
fibs.take(20) #=> [89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040]
fibs.next! #=> 832040
fibs.reset
Seq::Paged
Returns elements from a page one at a time.
require 'seq/paged'
s = Seq::Paged.new {|page| [page, page+1, page+2] }
s.take(10) #=> [0, 1, 2, 1, 2, 3, 2, 3, 4, 3]
# extra spacing added to show pages