我是初学者,所以请原谅我的无知,如果这是微不足道的话。
我有一个未知长度的javascript对象,每个属性的值都是一个数组(对我来说也是未知的长度)。例如:
var obj = {"varA":[1,2,3],
"varB":['good','bad'],
"varC":[0,100],
"varD":['low','med','high']
}
我想循环遍历每个属性,并为每个属性值组合创建一个新对象。如果我知道可以强制使用循环的属性数量,但有没有办法枚举而不知道有多少循环硬编码?
我基本上想做这样的事情:
var oblist = [];
for (a in varA){
for (b in varB){
for (c in varC){
for (d in varD){
oblist.push({"varA":varA[a], "varB":varB[b], "varC":varC[c], "varD":varD[d]});
}
}
}
}
因此,oblist将包含如下对象:
{"varA":1, "varB":"good", "varC":0, "varD":"low"}
{"varA":1, "varB":"good", "varC":0, "varD":"med"}
...
{"varA":3, "varB":"bad", "varC":100, "varD":"high"}
谢谢!
编辑: 看,我不是要求for循环或索引语法帮助。我问如果我不知道对象中的属性数量该怎么办(例如varA,varB,varC,varD,varE,hell我可以拥有我所知道的varZZ),所以我不能只是努力 - 代码4 for循环。有没有办法使用obj [Object.keys(obj)[i]]。length?
来设置它答案 0 :(得分:1)
var obj = {"varA":[1,2,3],
"varB":['good','bad'],
"varC":[0,100],
"varD":['low','med','high']
}
// flatten the object into an array so it's easier to work with
var obj2list = function(obj) {
var list = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
list.push({
name: key,
val: obj[key]
});
}
}
return list;
};
// implement your favorite version of clone...this isn't particular fast
var cloneObj = function(obj) {
return JSON.parse(JSON.stringify(obj));
}
var iterateAndPopulateCombo = function(currentObj, listToIterate, result) {
if (listToIterate.length == 0) {
result.push(currentObj);
} else {
listToIterate[0].val.forEach(function(d) {
var newObj = cloneObj(currentObj);
newObj[listToIterate[0].name] = d;
iterateAndPopulateCombo(newObj, listToIterate.slice(1), result);
})
}
}
var list = obj2list(obj);
var result = [];
iterateAndPopulateCombo({}, list, result);
console.log(JSON.stringify(result));
document.body.appendChild(document.createTextNode(JSON.stringify(result)));
答案 1 :(得分:1)
你需要的组合是你obj中所有数组的cartesian product
,这里有一个小提琴,显示它在行动:
http://jsfiddle.net/sifriday/qmyxhhny/2/
代码......
// I think the combo you're after is known as cartesian product
// Here's a function to do it, from:
// http://stackoverflow.com/questions/12303989/cartesian-product-of-multiple-arrays-in-javascript
// It needs Underscore.js
function cartesianProductOf() {
return _.reduce(arguments, function(a, b) {
return _.flatten(_.map(a, function(x) {
return _.map(b, function(y) {
return x.concat([y]);
});
}), true);
}, [ [] ]);
};
// Here's your object
var obj = {"varA":[1,2,3],
"varB":['good','bad'],
"varC":[0,100],
"varD":['low','med','high']
}
// Now I extract the arrays from your object
var idx, jdx, keys = Object.keys(obj), arrays = [], result1 = [], result2 = []
for (idx in keys) {
var key = keys[idx]
var arr = obj[key]
arrays.push(arr)
}
// We can calculate the combos of the obj, but this isn't annotated.
result1 = cartesianProductOf.apply(null, arrays)
// Now turn these back into annotated objects.
for (idx in result1) {
var tmp = result1[idx], obj = {}
for (jdx in tmp) {
obj[keys[jdx]] = tmp[jdx]
}
result2.push(obj)
}
// Done!
console.log(result2)
经过一番努力,我认为可以整理一下;你可以确保注释发生在笛卡尔积中。