如何通过递归实现多选项数组的笛卡尔积变体生成?附示例
生成商品变体集合:递归与笛卡尔积方案
嘿,这个需求其实就是典型的多集合笛卡尔积场景——不管是用递归手动实现,还是直接基于笛卡尔积的思路来处理,都能完美搞定。下面我给你拆解两种方案,代码示例用JavaScript(毕竟你给的是JSON格式,大概率是前端/Node场景):
一、直接借助笛卡尔积实现(最直观)
笛卡尔积天生就是用来生成多个集合的所有可能组合的,刚好匹配你的变体生成需求。具体步骤:
- 从输入的
options中提取所有values数组,得到一个二维数组(比如你给的例子里就是[["Blue", "Black"], ["Small", "Large"]]) - 计算这个二维数组的笛卡尔积
- 将每个组合中的元素按顺序映射为
option1、option2...的键值对
代码示例
function generateVariants(options) { // 第一步:提取所有选项的values列表 const valueLists = options.map(opt => opt.values); // 第二步:计算笛卡尔积 const cartesianProduct = valueLists.reduce((accumulator, currentValues) => { return accumulator.flatMap(prevCombination => currentValues.map(val => [...prevCombination, val]) ); }, [[]]); // 第三步:转换为要求的variant格式 const variants = cartesianProduct.map(combination => { return combination.reduce((variantObj, value, index) => { variantObj[`option${index + 1}`] = value; return variantObj; }, {}); }); return { variants }; } // 测试你的输入 const inputOptions = [ { "name": "Color", "values": [ "Blue", "Black" ] }, { "name": "Size", "values": [ "Small", "Large" ] } ]; console.log(JSON.stringify(generateVariants(inputOptions), null, 2));
运行这段代码后,就能得到你期望的输出格式。
二、递归实现(手动构建笛卡尔积)
递归是实现笛卡尔积的经典方式,核心思路是逐步缩小问题规模,直到触达终止条件再回溯拼接结果:
- 终止条件:如果只剩一个选项数组,直接返回该数组中每个元素对应的单元素组合
- 递归过程:先递归处理除第一个外的所有选项数组,得到它们的笛卡尔积;再将第一个数组的每个元素,与递归得到的每个组合进行拼接,生成新的完整组合
递归版代码示例
// 递归计算笛卡尔积的核心函数 function recursiveCartesian(arrays) { // 终止条件:只剩一个数组,返回每个元素的单元素数组 if (arrays.length === 1) { return arrays[0].map(value => [value]); } // 递归处理剩余的数组 const remainingCombinations = recursiveCartesian(arrays.slice(1)); // 将当前数组的每个元素与剩余组合拼接 return arrays[0].flatMap(value => remainingCombinations.map(comb => [value, ...comb]) ); } function generateVariantsWithRecursion(options) { const valueLists = options.map(opt => opt.values); const cartesianCombinations = recursiveCartesian(valueLists); // 转换为要求的variant格式 const variants = cartesianCombinations.map(combination => { return combination.reduce((obj, val, idx) => { obj[`option${idx + 1}`] = val; return obj; }, {}); }); return { variants }; } // 测试 console.log(JSON.stringify(generateVariantsWithRecursion(inputOptions), null, 2));
总结
- 两种方法本质都是围绕笛卡尔积展开的,递归只是手动实现笛卡尔积的一种方式
- 不管
options有多少个选项组(比如再加一个"Style"选项),这两种方法都能自动适配,生成所有可能的变体组合,无需修改核心逻辑
内容的提问来源于stack exchange,提问作者infinitywarior
相关产品推荐
相关产品推荐

