Array#product

Added in v1.8 · Updated March 13, 2026 · Array Methods
ruby array enumerable

The .product method returns the cartesian product of arrays — all possible combinations of elements from each array. It produces a new array containing every possible pairing.

colors = [:red, :blue]
sizes = [:small, :large]

colors.product(sizes)
# => [[:red, :small], [:red, :large], [:blue, :small], [:blue, :large]]

Syntax

array.product(*other_arrays)
array.product(*other_arrays) { |combination| block }

Parameters

ParameterTypeDefaultDescription
*other_arraysArrayRequiredOne or more arrays to combine with

What .product Returns

.product returns a new array containing all possible combinations. Each combination is itself an array.

[1, 2].product([:a, :b])
# => [[1, :a], [1, :b], [2, :a], [2, :b]]

When called with no arguments, it returns an array of single-element arrays:

[1, 2, 3].product
# => [[1], [2], [3]]

Common Use Cases

Generating All Combinations

# Classic use: all size/color combinations
sizes = [:xs, :s, :m, :l, :xl]
colors = [:black, :white, :red]

sizes.product(colors)
# => [[:xs, :black], [:xs, :white], [:xs, :red], ... total 15 combinations]

Multiple Arrays

# Three or more arrays
[1, 2].product([:a, :b], [:x, :y])
# => [[1, :a, :x], [1, :a, :y], [1, :b, :x], [1, :b, :y],
#     [2, :a, :x], [2, :a, :y], [2, :b, :x], [2, :b, :y]]

With a Block

When given a block, .product yields each combination and returns nil:

[1, 2].product([:a, :b]) do |num, letter|
  puts "#{num}#{letter}"
end
# Output:
# 1a
# 1b
# 2a
# 2b
# => nil

Practical Example: Test Combinations

browsers = [:chrome, :firefox, :safari]
oses = [:windows, :macos, :linux]
versions = [100, 101, 102]

test_cases = browsers.product(oses, versions)
# Generate 27 test case combinations for automated testing

Creating a Grid

rows = 3
cols = 4

grid = (1..rows).to_a.product((1..cols).to_a)
# => [[1,1], [1,2], [1,3], [1,4], [2,1], ... [3,4]]

Performance Notes

  • The number of combinations grows exponentially: array1.size * array2.size * ...
  • For large arrays, this can create massive result sets
  • Use .each with blocks for memory-efficient iteration over combinations

Gotchas

Forgetting the Result

# Common mistake: not capturing the return value
[1, 2].product([:a, :b]) { |combo| puts combo }
# => nil (block returns nil, not the combinations!)

# Fix: use the return value
result = [1, 2].product([:a, :b])
# => [[1, :a], [1, :b], [2, :a], [2, :b]]

Empty Arrays

[1, 2].product([])
# => [] (empty array means no combinations)

[].product([:a, :b])
# => [] (empty receiver means no combinations)

See Also