0

let's say that i have the following array:

data[size] = Array('s', 'm');
data[color] = Array('blue', 'red');

I need a function that outputs me the following array

variations[] = Array('s', 'blue');
variations[] = Array('s', 'red');
variations[] = Array('m', 'blue');
variations[] = Array('m', 'red');

The function must work also on arrays like:

data[size] = Array('s', 'm', 'l');
data[color] = Array('blue', 'red');
data[version] = Array('run', 'walk');

It should give an array like

variations[] = Array('s', 'blue', 'run');
variations[] = Array('s', 'blue', 'walk');
variations[] = Array('s', 'red', 'run');
variations[] = Array('s', 'red', 'walk');

And so on ...

How can i implement it?

p.s.: if there is a specific name for this problem let me know so i'll edit the question title for future use

Scalax
  • 430
  • 1
  • 5
  • 12

3 Answers3

2

The following works having n arrays:

function cartesianProduct(data) {

    var current = [[]];
    for (var p in data) {
        var arr = data[p];
        var newCurrent = [];
        for (var c = 0; c < current.length; c++) {
            var baseArray = current[c];
            for (var a = 0; a < arr.length; a++) {
                var clone = baseArray.slice();
                clone.push(arr[a]);
                newCurrent.push(clone);
            }
        }
        current = newCurrent;
    }

    return current;
}

for the following data:

var data = {
    size: ['s', 'm'],
    color: ['blue', 'red'],
    version: ['run', 'walk', 'jump']
};

will return all the combinations:

var variations = [
    ["s","blue","run"],
    ["s","blue","walk"],
    ["s","blue","jump"],
    ["s","red","run"],
    ["s","red","walk"],
    ["s","red","jump"],
    ["m","blue","run"],
    ["m","blue","walk"],
    ["m","blue","jump"],
    ["m","red","run"],
    ["m","red","walk"],
    ["m","red","jump"]
];
Enrique Carro
  • 380
  • 1
  • 3
  • 15
0

Your syntax is no valid JS, it seems PHP.

I assume you have

var data = {
    size: ['s', 'm'],
    color: ['blue', 'red']
};

And you want

var variations = [
    ['s', 'blue'],
    ['s', 'red'],
    ['m', 'blue'],
    ['m', 'red']
];

To get that, you can use

var variations = [];
for (var i=0; i<data.size.length; ++i)
    for (var j=0; j<data.color.length; ++j)
        variations.push([data.size[i], data.color[j]]);
Oriol
  • 274,082
  • 63
  • 437
  • 513
0

Tried something fancy, working on local :

var variations = []
var str = "";
var ind = 0;
index = [];

for (var k in data)
{
    index[index.length] = k;
    str+="for(var i"+ind+" in data["+k+"])";
    ind++;
}
str += "{variations[variations.length] = [";
for (;ind >= 0; ind--)
{
    str+="data["+index[ind]+"][i"+ind+"]";
    if (ind > 0) str += ",";
    else str+="];";
}
str+= "}";

eval(str);

This allows to have any number of arrays in data =)

Hotted24
  • 502
  • 3
  • 8