使用PHP实现数组的笛卡尔积来处理商品规格

在商城项目中必不可少的就是商品,同时商品也有各种规格,规格的价格库存也不同

在优化商城项目的时候,选择将商品的内容、规格、库存和价格分三个表来写。将多个规格的 id 合并存在一个字段中,按照从小到大的顺序来排列,使用逗号分隔

想了一下递归的实现,还是决定用笛卡尔积的方法来操作

什么是笛卡尔积呢?

笛卡尔乘积是指在数学中,两个集合 X 和 Y 的笛卡尓积(Cartesian product),又称直积,表示为 X × Y,第一个对象是 X 的成员而第二个对象是 Y 的所有可能有序对的其中一个成员

下来就来处理商品规格的数据,每个商品有多少规格是不确定的,先定义一个数组

$arr = array(
    array('goods_spec_id' => 91, 'spec_id' => 1, 'spec_title' => '礼包', 'addr_title' => '椿萱款', 'goods_id' => 128),
    array('goods_spec_id' => 89, 'spec_id' => 1, 'spec_title' => '礼包', 'addr_title' => '女神款', 'goods_id' => 128),
    array('goods_spec_id' => 90, 'spec_id' => 1, 'spec_title' => '礼包', 'addr_title' => '少女款', 'goods_id' => 128),
    array('goods_spec_id' => 92, 'spec_id' => 7, 'spec_title' => '色号', 'addr_title' => 'R080', 'goods_id' => 128),
    array('goods_spec_id' => 93, 'spec_id' => 7, 'spec_title' => '色号', 'addr_title' => 'P081', 'goods_id' => 128),
    array('goods_spec_id' => 95, 'spec_id' => 5, 'spec_title' => '促销', 'addr_title' => '新品五折', 'goods_id' => 128),
    array('goods_spec_id' => 94, 'spec_id' => 7, 'spec_title' => '色号', 'addr_title' => 'R083', 'goods_id' => 128),
);

防止规格表的goods_spec_id排序没有顺序,所以我们定义一个方法来处理它,按照从小到大来排列,同时使用笛卡尔积去处理数组

function dikaer($arr) {
    $arr1 = array();
    $result = array_shift($arr);
    while ($arr2 = array_shift($arr)) {
        $arr1 = $result;
        $result = array();
        foreach ($arr1 as $v) {
            foreach ($arr2 as $v2) {
                if (!is_array($v)) {
                    $v = array($v);
                }

                if (!is_array($v2)) {
                    $v2 = array($v2);
                }

                $result[] = array_merge_recursive($v, $v2);
            }
        }
    }
    foreach ($result as $k => $v) {
        if (is_array($result[$k]['goods_spec_id'])) {
            sort($result[$k]['goods_spec_id']);
        }
    }
    return $result;
}

同时调用这个方法

$newArr = [];
foreach ($arr as $k => $v) {
    $specId = $v['spec_id'];
    unset($v['spec_id']);
    unset($v['spec_title']);
    unset($v['goods_id']);
    $newArr[$specId][] = $v;
}
$specArr = dikaer($newArr);

打印处理后的数据,看一下是什么样子


array(9) {
    [0]=>
    array(2) {
        ["goods_spec_id"]=>
    array(3) {
      [0]=>
      int(91)
      [1]=>
      int(92)
      [2]=>
      int(95)
    }
    ["addr_title"]=>
    array(3) {
            [0]=>
      string(15) "椿萱款"
            [1]=>
      string(4) "R080"
            [2]=>
      string(12) "新品五折"
    }
  }
//  ...部分省略
}

这样的数据基本上是我们想要的数据,但是还是要进一步处理

foreach ($specArr as $k => $v) {
    if (is_array($v['goods_spec_id'])) {
        $specArr[$k]['goods_spec_id'] = implode(',', $v['goods_spec_id']);
    }
    if (is_array($v['addr_title'])) {
        $specArr[$k]['addr_title'] = implode('', $v['addr_title']);
    }
}

var_dump($specArr);

使用 PHP 的 implode() 函数将数组元素组合为字符串,然后我们查看一下数据

array(9) {
  [0]=>
  array(2) {
        ["goods_spec_id"]=>
    string(8) "91,92,95"
        ["addr_title"]=>
    string(31) "椿萱款 R080 新品五折"
  }
  [1]=>
  array(2) {
        ["goods_spec_id"]=>
    string(8) "91,93,95"
        ["addr_title"]=>
    string(31) "椿萱款 P081 新品五折"
  }
//  ...部分省略
}

这样就得到了我们所需要的数据,将goods_spec_id存入数据库,addr_title用来在后台页面显示

发表评论

发表评论

*

沙发空缺中,还不快抢~