问题:
二维数组分别叫父数组和子数组,父数组的长度和子数组的长度不确定,需要列出所有的组合(每一个组合的长度等于父数组的长度,即每个子数组中取一项进行组合)
分析:
由于父数组的长度和子数组的长度不确定,造成问题难度变大。组合会有很多种,因此把所有组合放在一个数组里好处理。每一个组合里面有多项,也适合使用数组。所有最终结果也用一个二维数组表示。这个问题要分两种情况讨论,一种二维数组父数组长度是1时,组合结果就是本身;第二种情况就是二维数组父数组长度大于1时,这个最难处理,我们可以把这个数组拆分成父数组的第一个子数组和第二个子数组组合,把组合的二维数组和父数组第三项(包含)之后的子数组放到一个新数组中(新数组第一项是前面组合的二维数组,第二项是父数组的第三项,第三项是父数组第四项。。。),新数组重复上面的二种情况,特别之处就是新数组的第一项是二维数组,需要增加判断进行特殊处理。
方案:
上面分析说的有点晦涩,下面看代码理解吧!
function combination(dimensionalArr) {
const FLength = dimensionalArr.length;
if (FLength >= 2) {
const SLength1 = dimensionalArr[0].length;
const SLength2 = dimensionalArr[1].length;
const DLength = SLength1 * SLength2;
const temporary = new Array(DLength);
let index = 0;
for (let i = 0; i < SLength1; i++) {
for (let j = 0; j < SLength2; j++) {
if (Array.isArray(dimensionalArr[0][i])) {
temporary[index] = [].concat([...dimensionalArr[0][i], dimensionalArr[1][j]]);
} else {
temporary[index] = [].concat([dimensionalArr[0][i], dimensionalArr[1][j]]);
}
index++;
}
}
const newArray = new Array(FLength - 1);
newArray[0] = temporary;
for (let j = 2; j < FLength; j++) {
newArray[j - 1] = dimensionalArr[j];
}
return combination(newArray);
} else {
if (dimensionalArr[0] && dimensionalArr[0][0] && Array.isArray(dimensionalArr[0][0])) {
return dimensionalArr[0];
}
return dimensionalArr;
}
}
const testArr = [
['红', '黄', '蓝'],
['8G', '12G'],
['pro', 'plus'],
['huawei', 'honor']
];
const result = combination(testArr);
console.log('组合种类:' + result.length);
console.log(result);