複数の配列から、要素を1つずつ選んですべての組み合わせを生成するプログラムをPHPで書いてみました。
ただし、組み合わせをすべて生成すると組み合わせ爆発を起こす可能性がありますので、使う際は本当に必要か慎重に検討してください。
<?php
function iterateAllCombinations($sets, callable $callback)
{
$indexToKey = array_keys($sets);
self::iterateAllCombinationsRecursive($sets, count($sets), $indexToKey, $callback, 0, []);
}
// 再帰的に呼ぶための関数本体
function iterateAllCombinationsRecursive($sets, $countOfSets, $indexToKey, callable $callback, $n, $generatedCombination)
{
if($n >= $countOfSets)
{
// この部分で生成された組み合わせを引数として、callbackが毎回呼ばれる。
$callback($generatedCombination);
return;
}
$keyOfSet = $indexToKey[$n];
foreach($sets[$keyOfSet] as $e)
{
$generatedCombination[$keyOfSet] = $e;
self::iterateAllCombinationsRecursive($sets, $countOfSets, $indexToKey, $callback, $n+1, $generatedCombination);
}
}
下記は、$callback内で生成された組み合わせをため込んだ場合の使用例になります。
<?php
// 組み合わせを生成したい3つの配列
$sets = [
'key1' => ['A', 'B', 'C'],
'key2' => ['1', '2'],
'key3' => ['a', 'b'],
];
$allCombinations = [];
iterateAllCombinations($sets, function($combination) use(&$allCombinations){
$allCombinations[] = $combination;
});
// $allCombinationsは、下記のような、上記の3つの配列それぞれから1つ要素を選んだすべての組み合わせの配列になります。
/*
[
['key1' => 'A', 'key2' => '1', 'key3' => 'a'],
['key1' => 'A', 'key2' => '1', 'key3' => 'b'],
['key1' => 'A', 'key2' => '2', 'key3' => 'a'],
['key1' => 'A', 'key2' => '2', 'key3' => 'b'],
['key1' => 'B', 'key2' => '1', 'key3' => 'a'],
['key1' => 'B', 'key2' => '1', 'key3' => 'b'],
['key1' => 'B', 'key2' => '2', 'key3' => 'a'],
['key1' => 'B', 'key2' => '2', 'key3' => 'b'],
['key1' => 'C', 'key2' => '1', 'key3' => 'a'],
['key1' => 'C', 'key2' => '1', 'key3' => 'b'],
['key1' => 'C', 'key2' => '2', 'key3' => 'a'],
['key1' => 'C', 'key2' => '2', 'key3' => 'b'],
];
*/
コメント