记录一下商城商品多规格算法(笛卡尔积算法)

原数据

[{
    "name": "颜色",
    "attr_values": "白色,黑色"
}, {
    "name": "内存",
    "attr_values": "64G,128G"
}, {
    "name": "型号",
    "attr_values": "X,pro"
}]

目标数据

 [{
     "price": "0",
     "内存": "64G",
     "型号": "X",
     "颜色": "白色"
 }, {
     "price": "0",
     "内存": "64G",
     "型号": "pro",
     "颜色": "白色"
 }, {
     "price": "0",
     "内存": "128G",
     "型号": "X",
     "颜色": "白色"
 }, {
     "price": "0",
     "内存": "128G",
     "型号": "pro",
     "颜色": "白色"
 }, {
     "price": "0",
     "内存": "64G",
     "型号": "X",
     "颜色": "黑色"
 }, {
     "price": "0",
     "内存": "64G",
     "型号": "pro",
     "颜色": "黑色"
 }, {
     "price": "0",
     "内存": "128G",
     "型号": "X",
     "颜色": "黑色"
 }, {
     "price": "0",
     "内存": "128G",
     "型号": "pro",
     "颜色": "黑色"
 }]

代码

<?php
/**
 * 设置规格
 *
 * @param array $attr_group  例:[['name'=>'颜色','attr_values'=>'白色,红色']]
 * @param integer $index 第几轮
 * @param integer $row 第几行
 * @param array $keys
 * @param array $attrs
 * @return array
 */
function setAttr(array $attr_group, int $index = 0, array $keys = [], array $attrs = []) 
{
    static $row = 0;

    if ($index == 0) {
        foreach($attr_group as $i) {
            $keys[] = 0;
        }
    }

    if (isset($attr_group[$index])) {
        $attr_values = explode(',', $attr_group[$index]['attr_values']);
        foreach($attr_values as $key => $attr_value) {
            $keys[$index] = $key;
            if ($index + 1 == count($attr_group)) {
                foreach($keys as $i => $item) {
                    $attrs[$row][$attr_group[$i]['name']] = explode(',', $attr_group[$i]['attr_values'])[$item];
                }
                $attrs[$row]['price'] = '0';
                $row++;
            } else {
                $attrs = setAttr($attr_group, $index + 1, $keys, $attrs);
            }
        }
    }

    return $attrs;
}

//调用
$attr_group = [
    [
        'name' => '颜色',
        'attr_values' => '白色,红色'
    ], 
    [
        'name' => '内存',
        'attr_values' => '64G,128'
    ]
];
$attrs = setAttr($attr_group);
var_dump($attrs);

?>
本作品采用《CC 协议》,转载必须注明作者和本文链接
让PHP再次伟大
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 5

我提供一个思路:两两组合,新的组合再和剩下的组合递归

function getAttrGroups(array $initGrps, array $attrs){
    if(!$initGrps){
        return [];
    }
    if(!$attrs){
        return $initGrps;
    }
    // 两两组合
    $firstElem = array_shift($attrs);
    if(!is_array($firstElem)){
        return $initGrps;
    }
    $newGrps = [];
    foreach($initGrps as $grp){
        foreach($firstElem as $k2 => $v2){
            $newGrps[] = array_merge($grp, [$k2 => $v2]);
        }
    }
    // 再递归组合剩下的
    if($attrs){
        return getAttrGroups($newGrps, $attrs);
    }
    return $newGrps;
}

$attrs = [
    ['白色' => '颜色', '黑色' => '颜色',], 
    ['64G' => '内存', '128G' => '内存',], 
    ['Pro' => '型号', 'X' => '型号',], 
];
foreach($attrs[0] as $k => $v){
    $initGrps[] = [$k => $v];
}
$grps = getAttrGroups($initGrps, array_slice($attrs, 1));
$humanGrps = array_map(function($grp){
    $arr = [];
    foreach($grp as $val => $name){
        $arr[] = "{$name}:{$val}";
    }
    return implode(',', $arr);
}, $grps);

var_dump($humanGrps);
2年前 评论

用 reduce

2年前 评论
2年前 评论
勇敢的心 (楼主) 2年前

笛卡尔积的最佳实践

2年前 评论

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