0

I have an array:

$array[1] = ['a1','a2'];
$array[2] = ['b','c','d'];

I would like to achieve the following array:

['a1,'b']
['a1,'c']
['a1,'d']
['a1,'b','c']
['a1,'b','d']
['a1,'c','d']
['a1,'b','c','d']

['a2,'b']
['a2,'c']
['a2,'d']
['a2,'b','c']
['a2,'b','d']
['a2,'c','d']
['a2,'b','c','d']

!!important!! The value of $array[1] and $array[2] can have more than 2 items. Can have X items.

So far , this is my script:

  function getAllPermutations($array, $inb = false)
    {
        switch (count($array)) {
            case 1:
                return $array[0];
                break;
            case 0:
                echo 'Requires at least one array';
                break;
        }
        $keys = array_keys($array);
        $a = array_shift($array);
        $k = array_shift($keys);
        $b = getAllPermutations($array, 'recursing');

        $return = [];
        foreach ($a as $value) {
            if($value){
                foreach ($b as $value2) {
                    if (!is_array($value2))
                        $value2 = [$value2];

                    if((string) $inb === 'recursing') {
                        $return[] = array_merge([$value], (array) $value2);
                    }else {
                        $return[] = [$k => $value] + array_combine($keys, $value2);
                    }
                }
            }
        }

        return $return;
    }

and i get these values:

   [0] => Array
        (
            [1] => a1
            [2] => b
        )

    [1] => Array
        (
            [1] => a1
            [2] => c
        )

    [2] => Array
        (
            [1] => a1
            [2] => d
        )

    [3] => Array
        (
            [1] => a2
            [2] => b
        )

    [4] => Array
        (
            [1] => a2
            [2] => c
        )

    [5] => Array
        (
            [1] => a2
            [2] => d
        )

Any ideas on how should i fix this ? Thank you

Attila Naghi
  • 2,535
  • 6
  • 37
  • 59
  • [this](https://gist.github.com/cecilemuller/4688876) might help – berend Dec 15 '20 at 12:44
  • Does this answer your question? [How to generate in PHP all combinations of items in multiple arrays](https://stackoverflow.com/questions/8567082/how-to-generate-in-php-all-combinations-of-items-in-multiple-arrays) – Justinas Dec 15 '20 at 12:44
  • @Justinas , it is similar , but not the same – Attila Naghi Dec 15 '20 at 12:52
  • @berend thnx for the suggestion, but my issue is about getting the all of the keys as well. If you check my post, you can see i want to get `a1` with `b` and `c` and `d` and `'b','c','d'`, not only the combination with `bc` and `cd` and `bd`. – Attila Naghi Dec 15 '20 at 12:54

1 Answers1

0

I am not sure about using recursive function, but I can help you with simple force. Function below will generate all of combinations:

function permutations(array $elements): Generator
{
    $elementsCount = count($elements);
    foreach ($elements as $key => $element) {
        for ($offset = $key + 1; $offset < $elementsCount; $offset++) {
            for ($length = 1; $length < $elementsCount - $offset + 1; $length++) {
                yield array_merge(
                    [$element],
                    array_slice($elements, $offset, $length)
                );
            }
        }
    }
}

$list = ['a', 'b', 'c', 'd', 'e'];

foreach (permutations($list) as $permutation) {
    echo implode(',', $permutation) . PHP_EOL;
}

The result will be:

a,b
a,b,c
a,b,c,d
a,b,c,d,e
a,c
a,c,d
a,c,d,e
a,d
a,d,e
a,e
b,c
b,c,d
b,c,d,e
b,d
b,d,e
b,e
c,d
c,d,e
c,e
d,e

But we need little modification to fit your task:

<?php
function permutations(array $array): Generator
{
    $elements = $array[2];
    foreach ($array[1] as $node) {
        $elementsCount = count($elements);
        foreach ($elements as $key => $element) {
            yield array_merge(
                [$node],
                [$element]
            );
            for ($offset = $key + 1; $offset < $elementsCount; $offset++) {
                for ($length = 1; $length < $elementsCount - $offset + 1; $length++) {
                    yield array_merge(
                        [$node],
                        [$element],
                        array_slice($elements, $offset, $length)
                    );
                }
            }
        }
    }
}

$list = [
    1 => ['a1', 'a2'],
    2 => ['b', 'c', 'd']
];

foreach (permutations($list) as $permutation) {
    echo implode(',', $permutation) . PHP_EOL;
}

The result will be:

a1,b
a1,b,c
a1,b,c,d
a1,b,d
a1,c
a1,c,d
a1,d
a2,b
a2,b,c
a2,b,c,d
a2,b,d
a2,c
a2,c,d
a2,d

Here is demo

Urmat Zhenaliev
  • 1,497
  • 8
  • 22