Online store options and the Cartesian product
April 14th, 2010 by Bobby WhitmanA common situation: you are about to checkout at an online store, but before you can buy that new T-shirt you must first choose which color you want and select what size you wear.
You’ve likely never stopped to think about the data behind this simple interaction, but what really needs to happen is that based on these choices the application is actually selecting the specific inventory item you wish to purchase.
Let’s consider this same problem from the other side of the counter. Now, you are creating an online store and you have several lists of options that you must combine to form your inventory. How do you create every possible combination without missing any and without repeating? And, more importantly, how do you accomplish this programmatically so that store owner does not have to create each combo by hand (a task that quickly becomes overwhelming)?
In my elementary example you have a list of sizes {S, M, L, XL} and a list of colors {orange, red, blue, green}. Here it is quite simple: look at each color and make sure you have one item of each size for that color.
for( $i = 0; $i < count($colors); $i++ )
for( $j = 0; $j < count($sizes); $j++)
array_push( $combos, array( $colors[$i], $sizes[$j] ) );
But what if we have an unknown number of variables (maybe there is a third, or maybe there is a total of eight)? Our simple nested loop will no longer works when we don’t know how deep to go.
<mathspeak>
It helps to define this problem correctly, which is where the math comes in. Here, we have a finite number of finite sets and we wish to find all of the distinct ordered n-tuples who elements are the members of these sets. In other words, we want to find the Cartesian Product of the sets of our product options.
Symbolically…
if X1, X2, …, Xn are our sets of product options,
then, we want to calculate X1 × X2 × … × Xn = { (x1, x2, …, xn) | xi ∈ Xi }
This may look somewhat familiar from back in your days of graphing equations. The most common example of a Cartesian Product is what is called a Cartesian plane, or the x- and y- axes made up order pairs of numbers. Consider my original example, imagine labeling the x-axis with sizes and the y-axis with colors, the points then are your combinations. Same idea, just in more general terms.
</mathspeak>
Once we have the problem defined, we can tackle it programatically. My first reaction was to think recursion, but this problem can actually be solved quite elegantly in O(n2) time.