Class: Tap::Support::Combinator
- Includes:
- Enumerable
- Defined in:
- lib/tap/support/combinator.rb
Overview
Combinator provides a method for iterating over all combinations of items in the input sets.
c = Combinator.new [1,2], [3,4]
c.to_a # => [[1,3], [1,4], [2,3], [2,4]]
Combinators can take any object that responds to each as an input set; normally arrays are used.
Implementation
Combinator iteratively combines each element from the first set (a) with each element from the second set (b). When more than two sets are given, the second and remaining sets are bundled into a Combinator, which then acts as the second set.
c = Combinator.new [1,2], [3,4], [5,6]
c.a # => [[1],[2]]
c.b.class # => Combinator
c.b.a # => [[3],[4]]
c.b.b # => [[5],[6]]
Note that internally each item in a set is stored as a single-item array; the arrays are added during combination. Thus when iterating, the combinations are calculated like:
([1] + [3]) + [5] # => [1,3,5]
This is probably not the fastest implementation, but it works.
Instance Attribute Summary collapse
-
#a ⇒ Object
readonly
The first set.
-
#b ⇒ Object
readonly
The second set.
Instance Method Summary collapse
-
#each ⇒ Object
Passes each combination as an array to the input block.
-
#empty? ⇒ Boolean
True if length is zero.
-
#initialize(*sets) ⇒ Combinator
constructor
Creates a new Combinator.
-
#length ⇒ Object
Returns the number of combinations returned by each.
-
#sets ⇒ Object
Returns the sets used to initialize the Combinator.
Constructor Details
#initialize(*sets) ⇒ Combinator
Creates a new Combinator. Each input must respond to each, or be nil.
46 47 48 49 |
# File 'lib/tap/support/combinator.rb', line 46 def initialize(*sets) @a = make_set(sets.shift) @b = make_set(*sets) end |
Instance Attribute Details
#a ⇒ Object (readonly)
The first set
39 40 41 |
# File 'lib/tap/support/combinator.rb', line 39 def a @a end |
#b ⇒ Object (readonly)
The second set
42 43 44 |
# File 'lib/tap/support/combinator.rb', line 42 def b @b end |
Instance Method Details
#each ⇒ Object
Passes each combination as an array to the input block.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/tap/support/combinator.rb', line 74 def each # :yields: combination case when !(@a.empty? || @b.empty?) @a.each do |a| @b.each do |b| yield(a + b) end end when @a.empty? @b.each {|b| yield(b) } when @b.empty? @a.each {|a| yield(a) } end end |
#empty? ⇒ Boolean
True if length is zero.
57 58 59 |
# File 'lib/tap/support/combinator.rb', line 57 def empty? a.empty? && b.empty? end |
#length ⇒ Object
Returns the number of combinations returned by each.
62 63 64 65 66 67 68 69 70 71 |
# File 'lib/tap/support/combinator.rb', line 62 def length case when !(@a.empty? || @b.empty?) @a.length * @b.length when @a.empty? @b.length when @b.empty? @a.length end end |
#sets ⇒ Object
Returns the sets used to initialize the Combinator.
52 53 54 |
# File 'lib/tap/support/combinator.rb', line 52 def sets sets_in(a) + sets_in(b) end |