如何基于现有嵌套数组生成含value笛卡尔积组合的新数组?
如何从嵌套数组生成所有value字段的斜杠拼接组合数组
给定如下嵌套数组,需要生成一个新数组,其中每个元素的value字段是从原数组各子数组中取一个value值,通过斜杠拼接而成的所有可能组合:
const originalArray = [ [ { value: 'red', id: 99 }, { value: 'blue', id: 100 }, ], [ { value: 'small', id: 101 }, { value: 'medium', id: 102 }, ], [ { value: 'modern', id: 103 }, { value: 'classic', id: 104 }, ], ];
期望输出:
const newArrayBasedOnOriginalArray = [ { value: 'red/small/modern' }, { value: 'red/small/classic' }, { value: 'red/medium/modern' }, { value: 'red/medium/classic' }, { value: 'blue/small/modern' }, { value: 'blue/small/classic' }, { value: 'blue/medium/modern' }, { value: 'blue/medium/classic' }, ];
新数组长度为原数组各子数组长度的乘积,计算方式如下:
const lengthOfNewArray = originalArray .map(subArr => subArr.length) .reduce((curr, prev) => curr * prev); console.log('length of new array:', lengthOfNewArray); // 输出 8
解决方案:生成笛卡尔积并拼接字符串
这个问题本质是求多个数组的笛卡尔积,我们可以通过递归或迭代的方式实现,再将每个积元素的value字段用斜杠拼接,包装成目标格式的对象。
方法1:递归实现
function generateCombinations(arr) { // 递归终止:只剩最后一个子数组时,返回每个元素的value包装对象 if (arr.length === 1) { return arr[0].map(item => ({ value: item.value })); } // 递归处理剩余子数组的组合 const restCombinations = generateCombinations(arr.slice(1)); // 当前子数组元素与剩余组合拼接 return arr[0].flatMap(item => { return restCombinations.map(comb => ({ value: `${item.value}/${comb.value}` })); }); } // 使用示例 const result = generateCombinations(originalArray); console.log(result);
方法2:迭代实现(基于reduce)
function generateCombinations(arr) { return arr.reduce((acc, currSubArr) => { // 初始状态:处理第一个子数组,生成基础对象数组 if (acc.length === 0) { return currSubArr.map(item => ({ value: item.value })); } // 后续子数组与已有组合配对拼接 return acc.flatMap(comb => { return currSubArr.map(item => ({ value: `${comb.value}/${item.value}` })); }); }, []); } // 使用示例 const result = generateCombinations(originalArray); console.log(result);
代码说明
- 两种方法核心都是生成笛卡尔积:将每个子数组的元素与之前所有子数组的组合逐一配对。
flatMap用于扁平化数组,避免出现嵌套结构。- 最终每个组合都会被包装成
{ value: 拼接字符串 }的格式,完全匹配需求。
内容的提问来源于stack exchange,提问作者Qais Wardag
相关产品推荐
相关产品推荐

