11
8

More than 3 years have passed since last update.

PHPで組み合わせの全パターンを取得する

Posted at

何をするのか

配列の中から取り得るすべての組み合わせを取得します。

例えば,配列の要素が3つなら,1, 2, 3 いずれかの要素数を持つ組み合わせを作ります。

PHPで実装

/**
 * すべての組み合わせを返す
 *
 * @param array $arr 選ぶ元となる配列
 * @return array
 */
function getAllCombinations(array $arr): array
{
    $arr = array_unique($arr);
    $results = [[]];

    foreach ($arr as $item){
        foreach ($results as $result){ 
            $results[] = [$item, ...$result];
            // PHP7.4 未満
            // $results[] = array_merge([$item], $result);
        }
    }
    array_shift($results);
    return array_values($results);
}

使い方

// 3C3 + 3C2 + 3C1 = 7(組)
$arr = ['A', 'B', 'C'];
print_r(getAllCombinations($arr));

結果

Array
(
    [0] => Array
        (
            [0] => A
        )

    [1] => Array
        (
            [0] => B
        )

    [2] => Array
        (
            [0] => B
            [1] => A
        )

    [3] => Array
        (
            [0] => C
        )

    [4] => Array
        (
            [0] => C
            [1] => A
        )

    [5] => Array
        (
            [0] => C
            [1] => B
        )

    [6] => Array
        (
            [0] => C
            [1] => B
            [2] => A
        )

)

解説

外側の foreach を回す毎に,$results の中身がどう変化しているのかを見ればわかります。

配列 [A,B,C] があります。(クオーテーションは省略します)

初期時↓

[]

1回目のループ(A)終了時↓

[], @ [[A]]

2回目のループ(B)終了時↓

[], [[A]], @ [[B]], [[B],[A]]

3回目のループ(C)終了時↓

[], [[A]], [[B]], [[B],[A]], @ [[C]], [[C],[A]], [[C],[B]], [[C],[B],[A]]

@ 以降がそのループで追加された要素です。

ループの度に,現時点の \$results の各要素と \$item を結合した配列を \$results に追加していきます。

\$item 単体の組み合わせを作る為に,初期値の空配列が必要なのです。

参考

Finding All Element Combinations of an Array

11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8