尝试遍历多个嵌套数组以获取新数组中可能值的每个单个组合。
示例:
[
['a1', 'a2'],
['b1', 'b2'],
['c1', 'c2']
]
输出:
[
['a1'],
['a2'],
['b1'],
['b2'],
['c1'],
['c2'],
['a1', 'b1'],
['a1', 'b2'],
['a1', 'c1'],
['a1', 'c2'],
['a2', 'b1'],
['a2', 'b2'],
['a2', 'c1'],
['a2', 'c2'],
['b1', 'c1'],
['b1', 'c2'],
['b2', 'c1'],
['b2', 'c2']
]
我知道如何实现这一目标,也许我首先需要拆分数组?
答案 0 :(得分:3)
您可以使用两个嵌套的for
循环和一个参数来创建递归函数,以保持当前行迭代计数,以便您可以从此处开始下一个循环。
const data = [['a1', 'a2'], ['b1', 'b2'], ['c1', 'c2']]
const res = []
function comb(data, n = 0, prev = []) {
for (var i = n; i < data.length; i++) {
for (var j = 0; j < data[i].length; j++) {
let el = data[i][j]
let arr = prev.concat(el);
if (arr.length <= data[i].length) res.push(arr)
comb(data, i + 1, arr)
}
}
}
comb(data)
console.log(JSON.stringify(res))
答案 1 :(得分:3)
您可以采用递归方法,交出下一个索引并收集临时数组。
function getCombinations(array, max) {
function iter(i, j, temp) {
if (array[i] && j >= array[i].length) {
j = 0;
i++;
}
if (!array[i] || temp.length === max) return;
result.push(temp.concat(array[i][j]));
iter(i + 1, 0, temp.concat(array[i][j]));
iter(i, j + 1, temp);
}
var result = [];
iter(0, 0, []);
return result;
}
var array = [['a1', 'a2'], ['b1', 'b2'], ['c1', 'c2']],
result = getCombinations(array, 2);
console.log(result.map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:3)
如果您也需要排序(因此,首先是单个元素,最后是对),那也可以做到,只是它将比其他解决方案要长一点:
var org=[['a1', 'a2'],['b1', 'b2'],['c1', 'c2']];
var res=[];
// singles
org.forEach(arr => {
arr.forEach(elem => {
res.push([elem]);
});
});
// pairs
var start=0;
var end=res.length;
org.forEach(arr => {
start+=arr.length;
arr.forEach(elem => {
for(var i=start;i<end;i++)
res.push([elem,res[i][0]]);
});
});
console.log(JSON.stringify(res));
//singles
部分是一对嵌套的循环,推入所有元素,并且//pairs
再次遍历原始数组,只是利用了已经“展平”的结果end
只需保留单个元素的数量(随着数组长度的增加),start
总是跳到下一个子数组的开头(因此不会生成类似'a1','a2'
的对,因为它是必需的。