Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/enumerable.rb
Views: 11704
#1# This Module was developed by Thomas Hafner.2# No other references about the author.3#45# TITLE:6#7# Cartesian8#9# SUMMARY:10#11# Cartesian product and similar methods.12#13# AUTHORS:14#15# - Thomas Hafner1617#18module Enumerable1920class << self21# Provides the cross-product of two or more Enumerables.22# This is the class-level method. The instance method23# calls on this.24#25# Enumerable.cart([1,2], [4], ["apple", "banana"])26# #=> [[1, 4, "apple"], [1, 4, "banana"], [2, 4, "apple"], [2, 4, "banana"]]27#28# Enumerable.cart([1,2], [3,4])29# #=> [[1, 3], [1, 4], [2, 3], [2, 4]]3031def cartesian_product(*enums, &block)32result = [[]]33while [] != enums34t, result = result, []35b, *enums = enums36t.each do |a|37b.each do |n|38result << a + [n]39end40end41end42if block_given?43result.each{ |e| block.call(e) }44else45result46end47end4849alias_method :cart, :cartesian_product50end5152# The instance level version of <tt>Enumerable::cartesian_product</tt>.53#54# a = []55# [1,2].cart([4,5]){|elem| a << elem }56# a #=> [[1, 4],[1, 5],[2, 4],[2, 5]]5758def cartesian_product(*enums, &block)59Enumerable.cartesian_product(self, *enums, &block)60end6162alias :cart :cartesian_product6364# Operator alias for cross-product.65#66# a = [1,2] ** [4,5]67# a #=> [[1, 4],[1, 5],[2, 4],[2, 5]]68#69def **(enum)70Enumerable.cartesian_product(self, enum)71end7273# Expected to be an enumeration of arrays. This method74# iterates through combinations of each in position.75#76# a = [ [0,1], [2,3] ]77# a.each_combo { |c| p c }78#79# produces80#81# [0, 2]82# [0, 3]83# [1, 2]84# [1, 3]85#86def each_combo87a = collect{ |x|88x.respond_to?(:to_a) ? x.to_a : 0..x89}9091if a.size == 192r = a.shift93r.each{ |n|94yield n95}96else97r = a.shift98r.each{ |n|99a.each_combo{ |s|100yield [n, *s]101}102}103end104end105106# As with each_combo but returns combos collected in an array.107#108def combos109a = []110each_combo{ |c| a << c }111a112end113114end115116117