Class: Tins::Generator
- Includes:
- Enumerable
- Defined in:
- lib/tins/generator.rb
Overview
This class can create generator objects, that can produce all tuples, that would be created by as many for-loops as dimensions were given.
The generator
g = Tins::Generator[1..2, %w[a b c]]
produces
g.to_a # => [[1, "a"], [1, "b"], [1, "c"], [2, "a"], [2, "b"], [2, "c"]]
The ‘each’ method can be used to iterate over the tuples
g.each { |a, b| puts "#{a} #{b}" }
and Tins::Generator includes the Enumerable module, so Enumerable.instance_methods can be used as well:
g.select { |a, b| %w[a c].include? b } # => [[1, "a"], [1, "c"], [2, "a"], [2, "c"]]
Class Method Summary collapse
-
.[](*enums) ⇒ Object
Create a new Generator object from the enumberables enums.
Instance Method Summary collapse
-
#add_dimension(enum, iterator = :each) ⇒ Object
Add another dimension to this generator.
-
#each(&block) ⇒ Object
Iterate over all tuples produced by this generator and yield to them.
-
#initialize(enums) ⇒ Generator
constructor
Create a new Generator instance.
-
#recurse(tuple = [ nil ] * @n, i = 0) {|Array| ... } ⇒ Object
private
Recurses through nested enumerators to yield all combinations.
-
#size ⇒ Object
Return the size of this generator, that is the number of its dimensions.
Constructor Details
#initialize(enums) ⇒ Generator
Create a new Generator instance. Use the objects in the Array enums as dimensions. The should all respond to the :each method (see module Enumerable in the core ruby library).
27 28 29 30 |
# File 'lib/tins/generator.rb', line 27 def initialize(enums) @enums, @iterators, @n = [], [], 0 enums.each { |e| add_dimension(e) } end |
Class Method Details
.[](*enums) ⇒ Object
Create a new Generator object from the enumberables enums.
20 21 22 |
# File 'lib/tins/generator.rb', line 20 def self.[](*enums) new(enums) end |
Instance Method Details
#add_dimension(enum, iterator = :each) ⇒ Object
Add another dimension to this generator. enum is an object, that ought to respond to the iterator method (defaults to :each).
65 66 67 68 69 |
# File 'lib/tins/generator.rb', line 65 def add_dimension(enum, iterator = :each) @enums << enum @iterators << iterator @n += 1 end |
#each(&block) ⇒ Object
Iterate over all tuples produced by this generator and yield to them.
33 34 35 36 |
# File 'lib/tins/generator.rb', line 33 def each(&block) # :yield: tuple recurse(&block) self end |
#recurse(tuple = [ nil ] * @n, i = 0) {|Array| ... } ⇒ Object (private)
Recurses through nested enumerators to yield all combinations
This method performs a recursive traversal of nested enumerators, building tuples by iterating through each enumerator at its respective level and yielding complete combinations when the deepest level is reached
48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/tins/generator.rb', line 48 def recurse(tuple = [ nil ] * @n, i = 0, &block) if i < @n - 1 then @enums[i].__send__(@iterators[i]) do |x| tuple[i] = x recurse(tuple, i + 1, &block) end else @enums[i].__send__(@iterators[i]) do |x| tuple[i] = x yield tuple.dup end end end |
#size ⇒ Object
Return the size of this generator, that is the number of its dimensions.
72 73 74 |
# File 'lib/tins/generator.rb', line 72 def size @enums.size end |