From: "knu (Akinori MUSHA)" <noreply@...> Date: 2022-04-08T07:20:36+00:00 Subject: [ruby-core:108198] [Ruby master Feature#18685] Enumerator.product: Cartesian product of enumerators Issue #18685 has been reported by knu (Akinori MUSHA). ---------------------------------------- Feature #18685: Enumerator.product: Cartesian product of enumerators https://bugs.ruby-lang.org/issues/18685 * Author: knu (Akinori MUSHA) * Status: Open * Priority: Normal * Target version: 3.2 ---------------------------------------- I'd like to add a new Enumerator class method for generating the Cartesian product of given enumerators. A product here does not mean an accumulated array of arrays, but an enumerator to enumerate all combinations. ```ruby product = Enumerator.product(1..3, ["A", "B"]) p product.class #=> Enumerator product.each do |i, c| puts "#{i}-#{c}" end =begin output 1-A 1-B 2-A 2-B 3-A 3-B =end ``` This can be used to reduce nested blocks and allows for iterating over an indefinite number of enumerable objects. ## Implementation notes - It should internally use `each_entry` instead of `each` on enumerable objects to make sure to capture all yielded arguments from enumerable objects. - If no enumerable object is given, the block is called once with no argument. - It should reject a keyword-style hash argument so we can add keyword arguments in the future without breaking existing code. - Here's an example implementation: ```ruby # call-seq: # Enumerator.product(*enums) -> enum # Enumerator.product(*enums) { |*args| block } -> return value of args[0].each_entry {} def Enumerator.product(*enums, **kw, &block) kw.empty? or raise ArgumentError, "unknown keyword#{"s" if kw.size > 1}: #{kw.keys.map(&:inspect).join(", ")}" # TODO: size should be calculated if possible return to_enum(__method__, *enums, **kw) if block.nil? enums.reverse.reduce(block) { |inner, enum| ->(*values) { enum.each_entry { |value| inner.call(*values, value) } } }.call() end ``` - Not to be confused with `Enumerator.produce`. ���� ## Prior case - Python: https://docs.python.org/3/library/itertools.html#itertools.product -- https://bugs.ruby-lang.org/ Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>