问题
我想为类似模板的对象生成所有组合,该对象可能需要多个子对象,其中一些子对象将所需的输出定义为数组。这些 child 也可以生 child (几乎没有限制)。
输入示例
const input = {
a: [true, false],
b: ['first', 'second'],
c: {
d: [true, false]
}
};
输出示例
const output = [
{
a: true,
b: 'first',
c: {
d: true
}
},
{
a: true,
b: 'first',
c: {
d: false
}
},
{
a: true,
b: 'second',
c: {
d: true
}
},
{
a: true,
b: 'second',
c: {
d: false
}
},
//...
]
问题
将输入转换为输出的 JavaScript 函数是什么?
尝试过什么?
我尝试从这个问题中获取原始函数,并使其更符合 ES 标准,但是当对象中有多个子对象时,这不起作用。
function combinations(input, keyIndex = 0, current = {}, result = []) {
const keys = Object.keys(input)
const key = keys[keyIndex]
const values = input[key]
for (const index in values) {
current[key] = values[index]
if (keyIndex + 1 < keys.length) {
combinations(input, keyIndex + 1, current, result)
} else {
result.push(JSON.parse(JSON.stringify(current)))
}
}
return result;
}
最佳答案
如果包含对象的数组再次调用 getCartesian
并构建新对象,您可以采用递归函数来分隔所有键/值对并通过迭代值构建新的笛卡尔积。
这也适用于嵌套对象。
function getCartesian(object) {
return Object.entries(object).reduce((r, [k, v]) => {
var temp = [];
r.forEach(s =>
(Array.isArray(v) ? v : [v]).forEach(w =>
(w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
temp.push(Object.assign({}, s, { [k]: x }))
)
)
);
return temp;
}, [{}]);
}
var input = { a: [true, false], b: ['first', 'second'], c: { d: [true, false] } },
cartesian = getCartesian(input);
console.log(cartesian);
.as-console-wrapper { max-height: 100% !important; top: 0; }
关于javascript - 生成多维对象的所有组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53007778/