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
| Parameter | Type | Default | Description |
|---|---|---|---|
| *other_arrays | Array | Required | One 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
.eachwith 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
.combination- Generate all unordered combinations.flatten- Flatten nested arrays