Method: Enumerable.cross
- Defined in:
- lib/nano/enumerable/%3A%3Across.rb
.cross(*enums, &block) ⇒ Object
Provides the cross-product of two or more Enumerables.
This is the class-level method. The instance method
calls on this.
Enumerable.cross([1,2], [4], ["apple", "banana"])
#=> [[1, 4, "apple"], [1, 4, "banana"], [2, 4, "apple"], [2, 4, "banana"]]
Enumerable.cross([1,2], [3,4])
#=> [[1, 3], [1, 4], [2, 3], [2, 4]]
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/nano/enumerable/%3A%3Across.rb', line 18 def self.cross(*enums, &block) raise if enums.empty? gens = enums.map{|e| Generator.new(e)} return [] if gens.any? {|g| g.end?} sz = gens.size res = [] tuple = Array.new(sz) loop do # fill tuple (0 ... sz).each { |i| tuple[i] = gens[i].current } if block.nil? res << tuple.dup else block.call(tuple.dup) end # step forward gens[-1].next (sz-1).downto(0) { |i| if gens[i].end? if i > 0 gens[i].rewind gens[i-1].next else return res end end } end end |