Produto cartesiano de propriedades de objeto javascript
Eu tenho um objeto do seguinte formulário (caso de teste simplificado abaixo)
var test = {
shirts: {
sizes: ['large', 'medium']
,colors:['red', 'blue']
}
, trousers: {
type: ['formal', 'casual']
, pattern: ['plaid', 'stripes']
}
};
Desejo gerar um produto cartesiano das propriedades para que a saída seja uma matriz do seguinte formato:
// desired output
[ {shirts:{sizes:'large', color:'red'}, trousers:{type:'formal', pattern:'plaid'}}
,{shirts:{sizes:'large', color:'red'}, trousers:{type:'formal', pattern:'stripes'}}
,{shirts:{sizes:'large', color:'red'}, trousers:{type:'casual', pattern:'plaid'}}
, {shirts:{sizes:'large', color:'red'}, trousers:{type:'casual', pattern:'stripes'}}
,{shirts:{sizes:'large', color:'blue'}, trousers:{type:'formal', pattern:'plaid'}}
..... and so on ]
Como posso conseguir isso? Eu trabalhei com o código a seguir (com base em uma modificação de código para o produto cartesiano da matriz de outro post do SO), mas parece que estou me atando a nós tentando fazer com que isso funcione.
function myCartesianProduct(input, current) {
if (!input) { return []; }
var head = input[Object.keys(input)[0]];
var tail = objSlice(input);
var output = [];
for (var key in head) {
for (var i = 0; i < head[key].length; i++) {
var newCurrent = copy(current);
newCurrent[key] = head[key][i];
if (Object.keys(tail).length) { //if tail.length
var productOfTail =
myCartesianProduct(tail, newCurrent);
output = output.concat(productOfTail);
} else {
output.push(newCurrent);
}
}
}
return output;
}
function objSlice(obj) {
var slicedObj = angular.copy(obj); // copy object using angularJs copy method
delete slicedObj[Object.keys(slicedObj)[0]]; //delete the first key
return slicedObj;
};
function copy(obj) {
var res = {};
for (var p in obj) res[p] = obj[p];
return res;
}
console.log(myCartesianProduct(test));
Agradecemos antecipadamente a sua ajuda com isso!