• 7
いいね
• 5
コメント
に更新
6

# 非再帰版

Pythonの実装を参考に非再帰版で書き直しました。なかなかこんな書き方思いつかないよ…

```<?php

function direct_product(array ...\$arrays)
{
\$result = [[]];
foreach (\$arrays as \$array) {
\$tmp = [];
foreach (\$result as \$x) {
foreach (\$array as \$y) {
\$tmp[] = array_merge(\$x, [\$y]);
}
}
\$result = \$tmp;
}
return \$result;
}

var_export(direct_product(['A', 'B', 'C'], ['a'], [1, 2]));
/*
array (
0 =>
array (
0 => 'A',
1 => 'a',
2 => 1,
),
1 =>
array (
0 => 'A',
1 => 'a',
2 => 2,
),
2 =>
array (
0 => 'B',
1 => 'a',
2 => 1,
),
3 =>
array (
0 => 'B',
1 => 'a',
2 => 2,
),
4 =>
array (
0 => 'C',
1 => 'a',
2 => 1,
),
5 =>
array (
0 => 'C',
1 => 'a',
2 => 2,
),
)
*/

var_export(direct_product(['A', 'B', 'C'], [], [1, 2]));
/*
array (
)
*/

var_export(direct_product());
/*
array (
0 =>
array (
),
)
*/
```

↑最後のやつって数学的に正しいのだろうか？

# 再帰ジェネレータ版

```<?php

function direct_product(array ...\$arrays)
{
if (!\$arrays) {
yield [];
} elseif (\$tails = array_pop(\$arrays)) {
foreach (direct_product(...\$arrays) as \$body) {
foreach (\$tails as \$tail) {
yield array_merge(\$body, [\$tail]);
}
}
}
}

var_export(iterator_to_array(direct_product(['A', 'B', 'C'], ['a'], [1, 2])));
/*
array (
0 =>
array (
0 => 'A',
1 => 'a',
2 => 1,
),
1 =>
array (
0 => 'A',
1 => 'a',
2 => 2,
),
2 =>
array (
0 => 'B',
1 => 'a',
2 => 1,
),
3 =>
array (
0 => 'B',
1 => 'a',
2 => 2,
),
4 =>
array (
0 => 'C',
1 => 'a',
2 => 1,
),
5 =>
array (
0 => 'C',
1 => 'a',
2 => 2,
),
)
*/

var_export(iterator_to_array(direct_product(['A', 'B', 'C'], [], [1, 2])));
/*
array (
)
*/

var_export(iterator_to_array(direct_product()));
/*
array (
0 =>
array (
),
)
*/
```