我正在尝试基于2个数组生成所有可能数据的数组:
$arr1 = ['a', 'b', 'c'];
$arr2 = [true, false];
结果应该类似于:
[
[
"a" => true,
"b" => true,
"c" => true
],
[
"a" => true,
"b" => false,
"c" => true
],
[
"a" => true,
"b" => false,
"c" => false
],
[
"a" => true,
"b" => true,
"c" => false
],
[
"a" => false,
"b" => true,
"c" => true
]
...
]
这是我到目前为止所做的:
function generateAllCases($arr1, $arr2)
{
$resultArr = [];
foreach ($arr1 as $i => $elm)
{
array_shift($arr1);
foreach ($arr2 as $vis)
{
$resultArr[] =
[
$elm => $vis
];
$resultArr[] = $this->generateAllCases($arr1, $arr2);
}
}
return $resultArr;
}
generateAllCases(['a', 'b', 'c'], [true, false]);
我得到了正确的结果,但是数组没有按照我的建议格式化,我尝试了不同的方法来做,但是没有运气获得正确的结果。我无法解决这个问题。
编辑:如果有更好的循环方法,请告诉我。
任何帮助将不胜感激。
答案 0 :(得分:2)
似乎您正在寻找$arr2
的所有元素中的所有permutations with repetition,其长度为$arr1
中的元素数量。
如果是这样,则应该可以进行以下操作:
<?php
declare(strict_types=1);
error_reporting(-1);
ini_set('display_errors', 'On');
function pwr(array $elements, int $k, int $idx = 0, array &$result = []): \Generator
{
foreach ($elements as $element) {
$result[$idx] = $element;
if ($k - $idx > 1) {
yield from pwr($elements, $k, $idx + 1, $result);
}
else {
yield $result;
}
}
}
function gen(array $keys, array $values): \Generator
{
foreach (pwr($values, \count($keys)) as $set) {
yield array_combine($keys, $set);
}
}
// this is just to test the result in a more *visual* way
foreach (gen(range('a', 'j'), [true, false]) as $case) {
foreach ($case as $k => $v) {
echo $v ? $k : '_';
}
echo "\n";
}
为避免出现内存问题,可以使用yield
,但是如果绝对需要数组,请使用iterator_to_array
。
显然,这种增长非常快(\count($arr2) ** \count($arr1)
),因此在使用iterator_to_array
时要小心。
答案 1 :(得分:0)
我终于设法做到了。这不是最好的解决方案,但可以。另外,如果我们有10个以上的商品,则由于每次添加新商品都会使它成倍增加,因此该过程开始变慢:
public function generateAllCases($arr1, $arr2, $resultArr, &$index, $firstCall = false)
{
$shifted = false;
foreach ($arr1 as $elm)
{
foreach ($arr2 as $i => $vis)
{
if(!$shifted)
{
array_shift($arr1);
$shifted = true;
}
if(!isset($resultArr[$index]) || !isset($resultArr[$index][$elm]))
{
$resultArr[$index][$elm] = $vis;
}
else
{
$prevItem = $resultArr[$index];
$index++;
$resultArr[$index] = $prevItem;
$resultArr[$index][$elm] = $vis;
}
$resultArr = $this->generateAllCases($arr1, $arr2, $resultArr, $index);
}
break;
}
if($firstCall)
{
$allResults = [];
foreach ($resultArr as $k => $v)
{
$allResults[implode('.', $v)] = $v;
}
$allResults = array_values($allResults);
return $allResults;
}
return $resultArr;
}
这样称呼:
$index = 0;
$cases = $rpd->generateAllCases(['a', 'b', 'c'], [true, false], [], $index, true);