PHP数组多属性进行排列组合

抽象一下需求:

在构建某个对象时,它拥有多个属性,每个属性拥有多个可选的值,需要穷举出每个属性不同的选择组合构建出的不同对象,比如:

输入参数:

$arr = [
    'Name' => ['Jack', 'Lily', 'Martin'],
    'Age' => ['18', '12'],
    'Gender' => ['male', 'female'],
    'Address' => ['Alexander', 'Huston', 'NewYork'],
];

从每个属性中取一个值,根据排列组合计算知道可以得到 36 个不同的人。

期望结果:

篇幅原因,中间省略掉。

array (
  0 =>
  array (
    'Name' => 'Jack',
    'Age' => '18',
    'Gender' => 'male',
    'Address' => 'Alexander',
  ),
  1 =>
  array (
    'Name' => 'Jack',
    'Age' => '18',
    'Gender' => 'male',
    'Address' => 'Huston',
  ),

  ...

  34 =>
  array (
    'Name' => 'Martin',
    'Age' => '12',
    'Gender' => 'female',
    'Address' => 'Huston',
  ),
  35 =>
  array (
    'Name' => 'Martin',
    'Age' => '12',
    'Gender' => 'female',
    'Address' => 'NewYork',
  ),
)

实现代码:

/**
 * 排列组合
 * @param arr
 * @return array
 */
function pac(arr): array
{

    if (empty(arr)) {
        return [];
    }n = count(arr);   // 维度数量count = 1;         // 结果总数
    size = [];         // 每个属性的可选值个数visit = [];        // 每个属性当前访问到的位置(下标)
    keyIndex = [];     // 保存每个属性的keyres = [];          // 保存结果

    // 初始化
    i = 0;
    foreach (arr as key =>values) {
        size[i] = count(values);visit[i] = 0;count *= count(values);keyIndex[i] =key;
        i ++;
    }m = 0;
    temp = [];
    while (true) {

        for (i = 0; i<n; i++ ) {
            // 取当前位置的下一个位置记录到最终的数组中temp[m][i] = visit[i] + 1;
        }

        m ++;

        for (i = n - 1;i >= 0; i-- ) {
            // 取的是可选值的最后一个值时,重置位置记录,下一个组合从0位置开始
            if (visit[i] ==size[i] - 1) {visit[i] = 0;
            } else {
            // 当前属性未取完
                break;
            }
        }

        // 当所有属性的值都取完了,经过最后一次i--, i 值变为 -1,循环完成
        if (i < 0) {
            break;
        }
        // 位置后移
        visit[i] ++;

    }

    for (i = 0;i < count;i ++) {
        for (j = 0;j < n;j ++) {
            res[i][keyIndex[j]] = arr[keyIndex[j]][temp[i][j]-1];
        }
    }

    return $res;

}


如果需求是想要从多个元素中取n个出来,得到多种不同的结果,如果可选元素集合为['a', 'b','c'],n为2,这样传值:

$arr = [
    ['a', 'b','c'],
    ['a', 'b','c'],
];

得到的结果(部分):

array (
  0 =>
  array (
    0 => 'a',
    1 => 'a',
  ),
  1 =>
  array (
    0 => 'a',
    1 => 'b',
  ),

  ...

  7 =>
  array (
    0 => 'c',
    1 => 'b',
  ),
  8 =>
  array (
    0 => 'c',
    1 => 'c',
  ),
)
PHP数组多属性进行排列组合

原文链接:https://beltxman.com/3770.html,若无特殊说明本站内容为 行星带 原创,未经同意禁止转载。

发表评论

您的电子邮箱地址不会被公开。

Scroll to top