use strict; use warnings; use Set::CrossProduct; my @products = ('tshirt', 'pants', 'sweatshirt'); my %options = ( 'sizes' => ['small', 'medium', 'large'], 'colors' => ['red', 'green', 'blue'] ); # build an array of array my @p = (); push @p, \@products; push @p, $options{$_} for sort keys %options; # get all combinations my $iterator = Set::CrossProduct->new( \@p ); # print the combinations local $, = ' '; print "@$_\n" for (@{$iterator->combinations});