A few weeks ago, I came across a question about finding the cartesian product of two or more arrays in JavaScript. For anybody who is looking to do so, I posted the following code on stackoverflow:


function cartesianProductOf() {
  return Array.prototype.reduce.call(arguments, function(a, b) {
    var ret = [];
    a.forEach(function(a) {
      b.forEach(function(b) {
        ret.push(a.concat([b]));
      });
    });
    return ret;
  }, [[]]);
}

It is important to note that the above code will only work on newer browsers that implement Array.prototype.forEach() and Array.prototype.reduce(). If you must allow this function to be used on any browser or even in a stand-alone Windows Host Script, I would suggest using this version of jPaq which implements the functions if they aren’t already present. As of yet, I have not received any requests to see this in a JavaScript library. If you do want it in a library, let me know of your suggestions for a better name than cartesianProductOf. My issue with the name is that it is too long.

Categories: BlogJavaScript

9 Comments

Latia Ahmann · May 18, 2011 at 6:36 PM

Found your site on yahoo today and really liked it.. I bookmarked it and will be back to check it out some more later.

Mic92 · September 24, 2011 at 1:29 PM

Ruby just name it product. It is part of the Array class.
http://www.ruby-doc.org/core/classes/Array.html#M000291

Gavin Kistner · February 28, 2012 at 2:50 PM

Nice, and terse, implementation. You may be interested in a similar article I wrote about a Lazy Cartesian Product in JavaScript. It links to this page, and also summarizes and generalizes some of my contributions to the related Stack Overflow question. While your code here is great for creating an array of all combinations for the product, my code performs a lazy iteration through the combinations, yielding each before finding the next.

    Chris West · February 29, 2012 at 10:07 AM

    I am definitely interested in checking this out. Unfortunately, I don’t have time to right now, but I will look at your version as soon as I can. Thanks for the link.

viebel · September 29, 2012 at 2:54 PM

Thanks for sharing this nice piece of code.

I am suggesting the following improvement (using reduce, map and flatten from underscore) that is more functional-like because it doesn’t use mutable variables:

function cartesianProductOf() {
return _.reduce(arguments, function(a, b) {
return _.flatten(_.map(a, function(x) {
return _.map(b, function(y) {
return x.concat([y]);
});
}), true);
}, [ [] ]);
};

Look at it here: http://stackoverflow.com/a/12628791/813665

    Chris West · September 29, 2012 at 9:30 PM

    That is a good idea! One issue with this though is that it always relies on a JavaScript library. That is pretty cool though, thanks!

Leave a Reply to Mic92 Cancel reply

Your email address will not be published. Required fields are marked *