天天看點

PHP二維數組排列組合

最近遇到一個有關排列組合的計算問題:将多個使用者屬性(性别、地區、級别等)進行排列組合,并篩選出符合條件的使用者群體。除了作為篩選功能外,電商的SKU也可以利用這個算法求出所有的組合情況。

思路

排列組合是組合學最基本的概念。所謂排列,就是指從給定個數的元素中取出指定個數的元素進行排序。組合則是指從給定個數的元素中僅僅取出指定個數的元素,不考慮排序。——百度百科

以上是百度百科關于排列組合的描述,在這個場景中,其實就是把多個屬性的多個元素進行不重複的組合。如:

- 性别:男、女

- 級别:1級、2級、3級

- 地區:廣東、北京

組合出來有12種情況,即各屬性元素個數的乘積:

男、1級、廣東 女、1級、廣東
男、2級、廣東 女、2級、廣東
男、3級、廣東 女、3級、廣東
男、1級、北京 女、1級、北京
男、2級、北京 女、2級、北京
男、3級、北京 女、3級、北京

使用計算機的解題的思路是:周遊所有屬性,每次将一個屬性的所有元素放入最終結果集中,并将結果集作為模闆,代入下一個屬性計算中。

編碼

function combination(array $options)
{
    $rows = [];

    foreach ($options as $option => $items) {
        if (count($rows) > ) {
            // 2、将第一列作為模闆
            $clone = $rows;

            // 3、置空目前清單,因為隻有第一列的資料,組合是不完整的
            $rows = [];

            // 4、周遊目前列,追加到模闆中,使模闆中的組合變得完整
            foreach ($items as $item) {
                $tmp = $clone;
                foreach ($tmp as $index => $value) {
                    $value[$option] = $item;
                    $tmp[$index] = $value;
                }

                // 5、将完整的組合拼回原清單中
                $rows = array_merge($rows, $tmp);
            }
        } else {
            // 1、先計算出第一列
            foreach ($items as $item) {
                $rows[][$option] = $item;
            }
        }
    }

    return $rows;
}

$options = array(
    'sex' => [, ],
    'area' => [, , , , , , , , ],
    'level' => [, , , ],
);
$rows = combination($options);
           

原文連結:https://www.lbog.cn/blog/40