笛卡尔积的应用——商品 SKU 计算

什么是笛卡尔积

笛卡尔乘积是指在数学中,两个集合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)}。

商品 SKU 计算

PHP 版

public function cartesian($arr,$currentArr = []){
        //去除第一个元素
        $firstData = array_shift($arr);
        $first = $firstData["valueList"];
        if(empty($currentArr)){
            foreach ($first as $key => $value) {
                $currentArr[] = [
                    "spec_list" => [$value]
                ];
            }
        }else{
            $currentDataArr = [];
            // 如果是追加规格,遍历当前已处理好的规格
            foreach ($currentArr as $key => $value) {
                // 将当前规格追加到已处理好的规格之后
                foreach ($first as $currentKey => $currentValue) {
                    $item = array_merge($value["spec_list"],[$currentValue]);
                    $currentDataArr[] = [
                        "spec_list" => $item
                    ];
                }
            }
            $currentArr = $currentDataArr;
        }

        // 如果还有剩余的规格,再次调用
        if(count($arr) > 0){
            $surplusFirstArr = current($arr);
            if(isset($surplusFirstArr["valueList"]) && (count($surplusFirstArr["valueList"]) > 0) ){
                $currentArr = $this->cartesian($arr,$currentArr);
            }
        }
        return $currentArr;
    }

JS 版

function array_shift($array){
    return $array.shift();
}

function count($array){
    return $array.length;
}

function array_merge($left,$right){
    return $left.concat($right);
}
function cartesian($arr,$currentArr){
        //去除第一个元素
        let $firstData = array_shift($arr);
        let $first = $firstData["value_list"];
        if((!$currentArr) || ($currentArr.length == 0)){
            $currentArr = [];
            $first.forEach(($value,$key,$first) =>{
                $currentArr.push({
                    spec_group:[$value]
                });
            });
        }else{
            let $currentDataArr = [];
            // 如果是追加规格,遍历当前已处理好的规格
            $currentArr.forEach(($value,$key,$currentArr) =>{
                // 将当前规格追加到已处理好的规格之后
                $first.forEach(($currentValue,$currentkey,$first) =>{
                    let $item = array_merge($value["spec_group"],[$currentValue]);
                    $currentDataArr.push({
                        spec_group:$item
                    });
                });
            });
            $currentArr = $currentDataArr;
        }
        // 如果还有剩余的规格,再次调用
        if(count($arr) > 0){
            let $surplusFirstArr = $arr[0];
            if(($surplusFirstArr["value_list"]) && (count($surplusFirstArr["value_list"]) > 0) ){
                $currentArr = cartesian($arr,$currentArr);
            }
        }
        return $currentArr;
    }

案例

loongws/laravel-admin-sku

本作品采用《CC 协议》,转载必须注明作者和本文链接
www.haowuliaoa.com
本帖由系统于 1年前 自动加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 6

大佬辛苦了,按照你的思路,结合其它案例,跑起来了!

1年前 评论
22 (楼主) 1年前
DonnyLiu

大佬,厉害啊

1年前 评论

是这个吗

Illuminate\Support\Arr::crossJoin()
1年前 评论
22 (楼主) 1年前

大佬 如此优秀

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!