【发布时间】:2014-12-29 03:14:27
【问题描述】:
我有一个如下形式的对象(下面是简化的测试用例)
var test = {
shirts: {
sizes: ['large', 'medium']
,colors:['red', 'blue']
}
, trousers: {
type: ['formal', 'casual']
, pattern: ['plaid', 'stripes']
}
};
我想生成属性的笛卡尔积,以便输出是以下形式的数组:
// 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 ]
我怎样才能做到这一点?我编写了以下代码(基于对另一篇 SO 帖子中数组笛卡尔积的代码的修改),但我似乎在试图让它发挥作用。
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));
在此先感谢您的帮助!
【问题讨论】:
-
@Paul,这种情况不同。我确实看到了其他帖子(并根据修改创建了代码),但在这种情况下有所不同,我们有嵌套对象属性而不是数组数组。
-
是的,我在想也许您可以将子对象上的 Object.keys() 与另一个问题中数组的笛卡尔积函数结合起来,然后将数组数组的输出重组为一组对象,比如
map
标签: javascript cartesian-product