笛卡尔积

笛卡尔乘积是指在数学中,两个集合 X 和 Y 的笛卡尓积(Cartesian product),又称直积,表示为 X × Y,第一个对象是 X 的成员而第二个对象是 Y 的所有可能有序对的其中一个成员。假设集合A = {a, b},集合B = {0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。

实现思路

  1. 先计算第一个集合和第二个集合的笛卡尔积,把结果保存为一个新集合。
  2. 然后再用新集合与下一个集合计算笛卡尔积,依此循环直到与最后一个集合计算笛卡尔积。

PHP实现

function diker($arr) {
    // 删除并返回第一元素
    $result                 = array_shift($arr);
    // 取第二组数据,开始遍历
    while ($curArr          = array_shift($arr)) {
        // 两组数据组合后产生新的数组,再次与后面的数组进行组合
        $lastArr            = $result;
        $result             = [];

        foreach ($lastArr as $lastVal) {
            foreach ($curArr as $curVal) {
                // 两组数据组合成新的数组
                $result[]   = [...(array)$lastVal, ...(array)$curVal];
            }
        }
    }

    return $result;
}

$iPhone14 = [
    [128, 256, 512],
    ['红色', '白色', '黑色', '蓝色', '紫色', '绿色'],
    ['入门款', 'Plus', 'Pro', 'Pro Max']
];

$skuAll = diker($iPhone14);
var_export($skuAll); // 一共72个组合

JavaScript实现

let iPhone14 = [
    [128, 256, 512],
    ['红色', '白色', '黑色', '蓝色', '紫色', '绿色'],
    ['入门款', 'Plus', 'Pro', 'Pro Max']
];

// 使用数组的reduce处理
let skuAll = iPhone14.reduce((x, y) => {
    let result = [];
    // 两组数据组合成新的数组
    x.forEach(x => y.forEach(y => result.push(x.concat([y]))));
    return result;
}, [[]]);

console.log(skuAll); // 一共72个组合