все варианты комбинаций массива

есть массив вида: $q = ['ab','cd','ef','12','34']; как можно получить все варианты комбинаций? т.е.:

ab    
abcd    
abcdef    
abcdef12    
abcdef1234    
  cdef1234    
    ef1234    
      1234    
        34    
    ef    
    ef12    
  cdef    
  cdef12    

и т.д.

сохраняя последовательность элементов первичного массива, как в примере, т.е. ab34 не подходит


Ответы (2 шт):

Автор решения: vp_arth

Если порядок не имеет значения, можно перебрать простой рекурсией:

function foo(array $q = [], string $prefix = '') {
    if (!$q) {
        return $prefix ? [$prefix] : [];
    }
    
    $head = array_shift($q);
    return array_merge(
        foo($q, $prefix),
        foo($q, $prefix . $head),
    );
}

foreach(foo(['ab','cd','ef','12','34']) as $item) echo $item, PHP_EOL;  
["34","12","1234","ef","ef34","ef12","ef1234","cd","cd34","cd12","cd1234","cdef","cdef34","cdef12","cdef1234","ab","ab34","ab12","ab1234","abef","abef34","abef12","abef1234","abcd","abcd34","abcd12","abcd1234","abcdef","abcdef34","abcdef12","abcdef1234"]
→ Ссылка
Автор решения: vp_arth

Текущую задачу можно решить нарезая массив двумя указателями:

function foo(array $q = []) {
    $n = count($q);
    for ($i=0; $i<$n; ++$i) {
        for ($j=$i; $j<$n; $j++) {
            yield implode('', array_slice($q, $i, $j-$i+1));
        }
    }
}

echo json_encode([...foo(['ab','cd','ef','12','34'])]), PHP_EOL;
["ab","abcd","abcdef","abcdef12","abcdef1234","cd","cdef","cdef12","cdef1234","ef","ef12","ef1234","12","1234","34"]
→ Ссылка