I have an array:
[0 => 'перший', 1 => 'другий', 2 => 'третій']
I need to get:
[0 => 'перший', 1 => 'другий', 2 => 'третій'],
[0 => 'перший', 2 = > 'третій', 1 => 'другий'],
[1 => 'другий, 0 => 'перший', 2 => 'третій'],
[1 => 'другий ', 2 = > 'третій, 0 => 'перший'],
[2 => 'третій', 0 => 'перший', 1 = > 'другий'],
[2 => 'третій', 1 => 'другий', 0 = > 'перший']
I wrote a function:
function permutations($inArray, &$returnArray = [], $inProcessedArray = [])
{
if (count($inArray) === 1)
{
$returnArray[] = array_merge($inProcessedArray, $inArray);
}
else
{
foreach($inArray as $key => $value)
{
$copyArray = $inArray;
unset($copyArray[$key]);
permutations($copyArray, $returnArray, array_merge($inProcessedArray, [$key => $value]));
}
}
}
But this returns array elements permutations without preserving keys
Any suggestions? Thanks in advance
CodePudding user response:
Using the generator permutations from: https://stackoverflow.com/a/27160465/
$hash = [
0=>'Apple',
1=>'Banana',
2=>'Peach'
];
function permutations(array $elements)
{
if (count($elements) <= 1) {
yield $elements;
} else {
foreach (permutations(array_slice($elements, 1)) as $permutation) {
foreach (range(0, count($elements) - 1) as $i) {
yield array_merge(
array_slice($permutation, 0, $i),
[$elements[0]],
array_slice($permutation, $i)
);
}
}
}
}
$result = [];
foreach(permutations(array_keys($hash)) as $keys) {
$row = [];
foreach($keys as $k) {
$row[$k] = $hash[$k];
}
$result[] = $row;
}
var_export($result);
Output:
array (
0 =>
array (
0 => 'Apple',
1 => 'Banana',
2 => 'Peach',
),
1 =>
array (
1 => 'Banana',
0 => 'Apple',
2 => 'Peach',
),
2 =>
array (
1 => 'Banana',
2 => 'Peach',
0 => 'Apple',
),
3 =>
array (
0 => 'Apple',
2 => 'Peach',
1 => 'Banana',
),
4 =>
array (
2 => 'Peach',
0 => 'Apple',
1 => 'Banana',
),
5 =>
array (
2 => 'Peach',
1 => 'Banana',
0 => 'Apple',
),
)
CodePudding user response:
This is over-egging the pudding somewhat. But given such a small array, we can loop over many combinations and filter accordingly.
I'm sure there is something more elegant, but this does the trick.
<?php
$result = [];
for($i=0; $i<3; $i ) {
for($j=0; $j<3; $j ) {
for($k=0; $k<3; $k ) {
$row = [$i=>$hash[$i], $j=>$hash[$j], $k=>$hash[$k]];
if(count($row) == 3)
$result[] = $row;
}
}
}
Output:
array (
0 =>
array (
0 => 'Apple',
1 => 'Banana',
2 => 'Peach',
),
1 =>
array (
0 => 'Apple',
2 => 'Peach',
1 => 'Banana',
),
2 =>
array (
1 => 'Banana',
0 => 'Apple',
2 => 'Peach',
),
3 =>
array (
1 => 'Banana',
2 => 'Peach',
0 => 'Apple',
),
4 =>
array (
2 => 'Peach',
0 => 'Apple',
1 => 'Banana',
),
5 =>
array (
2 => 'Peach',
1 => 'Banana',
0 => 'Apple',
),
)