Javascript中二维数组的所有可能组合

9

我有一个包含变长数组的变长数组。例如,像这样:

var arr2d = [
    ['red', 'blue'],
    ['cotton','polyester','silk'],
    ['large','medium','small']
]

我正在尝试获取每个数组中一个元素的所有可能组合。因此,答案应该类似于这样:
var answer = [
    ['red', 'cotton', 'large'],
    ['red', 'cotton', 'medium'],
    ['red', 'cotton', 'small'],
    ['red', 'polyester', 'large'],
    .
    .
    .
]

我已经研究了此主题上的其他答案,但它们都是使用 Java(我需要 JavaScript),并且它们正在寻找所有组合而不仅仅是length === arr2d.length的组合。我已经花了将近两个小时来研究这个问题,但我仍然无法想到一种递归的方法。这是一个头脑爆炸的场景,因为这两个数组的长度都不同(我有一个包含这些 2D 数组的数组,我必须获取其中的组合)。在我提供的示例中,只有18种可能性,但实际上可能会有成千上万种可能性。

1
可能是JavaScript中多个数组的笛卡尔积的重复问题。 - Robby Cornelissen
2个回答

25

在使用递归函数时,另一个选项是在函数的参数中维护状态。这有时可以使函数更易于理解:

var arr2d = [['red', 'blue'],['cotton','polyester','silk'],['large','medium','small']]

function combos(list, n = 0, result = [], current = []){
    if (n === list.length) result.push(current)
    else list[n].forEach(item => combos(list, n+1, result, [...current, item]))
 
    return result
}

console.log(combos(arr2d))


2
我的天啊!只有五行代码!你今天赢得了互联网先生! - user10302261
1
这样一个整洁的答案,说实话让我想起了我需要加强递归能力。 - Essameldeen Youssef
1
我认为这是最有效的方法,我费尽心思想你是如何得出答案的。 - Fadhil Ahmad

5

这里提供一种递归解决方案。其思路是先取出第一个元素数组,对剩余的元素数组进行递归组合,最后将结果合并:

const arr2d = [
  ['red', 'blue'],
  ['cotton', 'polyester', 'silk'],
  ['large', 'medium', 'small']
];

function combinations(arr) {
  if (arr.length === 0) return [[]];
  let res = [], [first, ...rest] = arr;
  let remaining = combinations(rest);
  first.forEach(e => {
    remaining.forEach(smaller => {
      res.push([e].concat(smaller));
    });
  });
  return res;
}

console.log(combinations(arr2d));


1
非常快速和简短!非常感谢! - user10302261
我刚学到这个操作被称为笛卡尔积。 - user10302261
1
Mark Meyer 给了我们一个五行代码的解决方案。只是让你知道,供您个人使用。 - user10302261
等等,如果@CapitalJusticeWarrior说他需要所有可能性,那么除了解决方案之外,您还需要旋转初始数组以获得所有54种可能性。让结果= []; 对于(让我=0; 我<arr2d.length; 我++){ 让arr =组合(arr2d); 结果=结果.concat(arr); arr2d.push(arr2d [i]); arr2d.shift(); } 控制台.log(结果); - Sergey Pleshakov
如果数组中所有元素的索引都很重要(例如 [ 'medium', 'blue', 'large' ],[ 'large', 'medium', 'blue' ],[ 'blue', 'medium', 'large' ]),那就更需要考虑了。 - Sergey Pleshakov
@SergeyPleshakov 我们不关心排列(其中顺序很重要)。因此,我认为这里的总最终结果是 2 * 3 * 3 = 18 - slider

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接