产品SKU设计与笛卡尔积-PHP版

什么是笛卡尔积

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

在PHP中的实现

基础实现

public function singleDescartes(array $list): array{
        $a = array_shift($list);
        !is_array($a) && ($a = [$a]);
        $a = array_chunk($a, 1);
        do{
            $result = [];
            $b = array_shift($list);
            !is_array($b) && ($b = [$b]);
            foreach ($a as $p) {
                foreach (array_chunk($b, 1) as $q) {
                    $result[] = array_merge($p, $q);
                }
            }
            $a = $result;
        }while(!empty($list));
        return $result;
}


$list = [
    ['黑色','红色'],
    ['标准','加棉'],
    ['37码','38码','39码'],
];
$re = singleDescartes($list);
print_r(json_encode($re, JSON_UNESCAPED_UNICODE));
// output
[
    ["黑色", "标准", "37码"],
    ["黑色", "标准", "38码"],
    ["黑色", "标准", "39码"],
    ["黑色", "加棉", "37码"],
    ["黑色", "加棉", "38码"],
    ["黑色", "加棉", "39码"],
    ["红色", "标准", "37码"],
    ["红色", "标准", "38码"],
    ["红色", "标准", "39码"],
    ["红色", "加棉", "37码"],
    ["红色", "加棉", "38码"],
    ["红色", "加棉", "39码"]
]

扩展到项目

public function descartes(array $attrWithOptions): array{
        $a = array_shift($attrWithOptions);
        $a['options'] = array_chunk($a['options'], 1);
        do{
            $b = array_shift($attrWithOptions);
            $r = [
                'attrName' => "{$a['attrName']}+{$b['attrName']}",
                'options' => []
            ];
            foreach ($a['options'] as $option1) {
                foreach (array_chunk($b['options'], 1) as $option2) {
                    $r['options'][] = array_merge($option1, $option2);
                }
            }
            $a = $r;
        } while (count($attrWithOptions) > 0);
        return $r;
}


$list = [
            [
                'attrId' => 1,
                'attrName' => '容量',
                'options' => [
                    ['id' => 34, 'title' => '64G'],
                    ['id' => 35, 'title' => '128G']
                ]
            ],
            [
                'attrId' => 2,
                'attrName' => '颜色',
                'options' => [
                    ['id' => 43, 'title' => '玫瑰金'],
                    ['id' => 44, 'title' => '银色'],
                    ['id' => 45, 'title' => '黑色']
                ]
            ],
            [
                'attrId' => 3,
                'attrName' => '网络',
                'options' => [
                    ['id' => 53, 'title' => '联通'],
                    ['id' => 54, 'title' => '移动'],
                    ['id' => 55, 'title' => '电信']
                ]
            ]
];
$re = descartes($list);
print_r(json_encode($re, JSON_UNESCAPED_UNICODE));
// output
{
    "attrName": "容量+颜色+网络",
    "options": [
    [
        {"id": 34, "title": "64G"}, {"id": 43, "title": "玫瑰金"}, {"id": 53, "title": "联通"}],
        [{"id": 34, "title": "64G"}, {"id": 43, "title": "玫瑰金"}, {"id": 54, "title": "移动"}],
        [{"id": 34, "title": "64G"}, {"id": 43, "title": "玫瑰金"}, {"id": 55, "title": "电信"}],
        [{"id": 34, "title": "64G"}, {"id": 44, "title": "银色"}, {"id": 53, "title": "联通"}],
        [{"id": 34, "title": "64G"}, {"id": 44, "title": "银色"}, {"id": 54, "title": "移动"}],
        [{"id": 34, "title": "64G"}, {"id": 44, "title": "银色"}, {"id": 55, "title": "电信"}],
        [{"id": 34, "title": "64G"}, {"id": 45, "title": "黑色"}, {"id": 53, "title": "联通"}],
        [{"id": 34, "title": "64G"}, {"id": 45, "title": "黑色"}, {"id": 54, "title": "移动"}],
        [{"id": 34, "title": "64G"}, {"id": 45, "title": "黑色"}, {"id": 55, "title": "电信"}],
        [{"id": 35, "title": "128G"}, {"id": 43, "title": "玫瑰金"}, {"id": 53, "title": "联通"}],
        [{"id": 35, "title": "128G"}, {"id": 43, "title": "玫瑰金"}, {"id": 54, "title": "移动"}],
        [{"id": 35, "title": "128G"}, {"id": 43, "title": "玫瑰金"}, {"id": 55, "title": "电信"}],
        [{"id": 35, "title": "128G"}, {"id": 44, "title": "银色"}, {"id": 53, "title": "联通"}],
        [{"id": 35, "title": "128G"}, {"id": 44, "title": "银色"}, {"id": 54, "title": "移动"}],
        [{"id": 35, "title": "128G"}, {"id": 44, "title": "银色"}, {"id": 55, "title": "电信"}],
        [{"id": 35, "title": "128G"}, {"id": 45, "title": "黑色"}, {"id": 53, "title": "联通"}],
        [{"id": 35, "title": "128G"}, {"id": 45, "title": "黑色"}, {"id": 54, "title": "移动"}],
        [{"id": 35, "title": "128G"}, {"id": 45, "title": "黑色"}, {"id": 55, "title": "电信"}]
    ]
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一米没有

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值