listing variations of product attributes

The situation is the following:

In my app every product has attributes. for example a shirt has color,
neck size and sleeve size.

A jacket has color and jacket size.

Those attributes have values.

Colors: black, white, green, red etc
Neck size: 14, 15, 16, 16 etc
sleeve size: 20,21,22,23,24 etc
jacket size: S, M, L, XL

what I want to achieve is dynamically list all the available combination
(variation) of attributes for a specific type of product.

for example:

a shirt can have a combination of 4 colors, 5 neck sizes and 7 sleeve
sizes = 140

so I want my app to list all the available variations for shirts like

black, 14, 20
black, 14, 21
black, 14, 22
...
and so on (all 140 variations in this case)

so first I want to loop through sleeve size attributes, and then neck
size and finally colors.

what's the best solution to achieve that? it has to be dynamic, so if
the product is a jacket it has to know that it has 2 attributes (color
and size) so it will loop through those like this:

black, S
black, M
black, L
black, XL
white, S
white, M
....
and so on.

has anyone encountered that kind of problem and found a good solution?

Thanks for everyone.

Mark Ro wrote:

The situation is the following:

In my app every product has attributes. for example a shirt has color,
neck size and sleeve size.

A jacket has color and jacket size.

Those attributes have values.

Colors: black, white, green, red etc
Neck size: 14, 15, 16, 16 etc
sleeve size: 20,21,22,23,24 etc
jacket size: S, M, L, XL

irb(main):001:0> class Array
irb(main):002:1> def cross(other)
irb(main):003:2> inject([]) {|a,b| other.map {|c| a << [b,c].flatten};a}
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> [:black, :white].cross [14,15].cross %w{S M L}
(irb):6: warning: parenthesize argument(s) for future version
=> [[:black, 14, "S"], [:black, 14, "M"], [:black, 14, "L"], [:black,
15, "S"], [:black, 15, "M"], [:black, 15, "L"], [:white, 14, "S"],
[:white, 14, "M"], [:white, 14, "L"], [:white, 15, "S"], [:white, 15,
"M"], [:white, 15, "L"]]
irb(main):007:0>

fix that parenthesize thingy and you should be good to go..

hth

ilan