Finding the Cartesian product of two sets is really simple:
function product(f, xs, ys) {
var zs = [];
var m = xs.length;
var n = ys.length;
for (var i = 0; i < m; i++) {
var x = xs[i];
for (var j = 0; j < n; j++) {
var y = ys[j];
var z = f(x, y);
zs.push(z);
}
}
return zs;
}
For example, if you want the cartesian product of ["a","b"]
and ["c","z"]
:
var xs = ["a","b"];
var ys = ["c","z"];
var zs = product(add, xs, ys); // ["ac", "az", "bc", "bz"]
function add(a, b) {
return a + b;
}
If you want to find the cartesian product of more than one set then you could use reduce
:
var xss = [["a","b"],["c","z"],["d","e","f"]];
var xs = xss.reduce(productAdd); // ["acd","ace","acf",
// "azd","aze","azf",
// "bcd","bce","bcf",
// "bzd","bze","bzf"]
function productAdd(xs, ys) {
return product(add, xs, ys);
}
However you would need to filter
out empty sets:
var yss = [[],["b","z"],["d","e","f"]];
var ys = yss.filter(nonEmpty).reduce(productAdd); // ["bd","be","bf",
// "zd","ze","zf"]
function nonEmpty(xs) {
return xs.length > 0;
}
function productAdd(xs, ys) {
return product(add, xs, ys);
}
The reason we need to do this is pretty simple. Anything multiplied with 0
is 0
. Hence we remove all the zeros in the list of sets which we are multiplying.
Demo 1
var xss = [["a","b"],["c","z"],["d","e","f"]];
var xs = xss.reduce(productAdd);
alert(JSON.stringify(xs));
function productAdd(xs, ys) {
return product(add, xs, ys);
}
function add(a, b) {
return a + b;
}
function product(f, xs, ys) {
var zs = [];
var m = xs.length;
var n = ys.length;
for (var i = 0; i < m; i++) {
var x = xs[i];
for (var j = 0; j < n; j++) {
var y = ys[j];
var z = f(x, y);
zs.push(z);
}
}
return zs;
}
Demo 2
var yss = [[],["b","z"],["d","e","f"]];
var ys = yss.filter(nonEmpty).reduce(productAdd);
alert(JSON.stringify(ys));
function nonEmpty(xs) {
return xs.length > 0;
}
function productAdd(xs, ys) {
return product(add, xs, ys);
}
function add(a, b) {
return a + b;
}
function product(f, xs, ys) {
var zs = [];
var m = xs.length;
var n = ys.length;
for (var i = 0; i < m; i++) {
var x = xs[i];
for (var j = 0; j < n; j++)
zs.push(f(x, ys[j]));
}
return zs;
}
Hope that helps.