PHP: Retornando todas as combinações possíveis de um array multidimensional
~ 8 mins
Acabei chegando a uma solução, que vou compartilhar aqui com vocês, mas que não me deixou lá muito satisfeito. Pra esse projeto específico resolvia e a fila de tarefas é grande, então bola pra frente (é dura a vida do programador)!
Vamos dar uma olhada no problema. Vejamos o array abaixo:
O que eu precisava fazer era retornar uma lista com as combinações, como o resultado abaixo:
A idéia então era uma função recursiva, que montaria o array final com as combinações. Pra cada ítem do primeiro registro do array multidimensional, a função teria que varrer todos os outros registros e montar as combinações. A lógica é simples, mas, na hora da execução, sem usar variáveis globais, só consegui fazer retornando uma string com delimitadores simples - o array é montado fora da função.
O primeiro problema era que o array original não possuía índices númericos. E como nossa função teria que ser de alguma forma progressiva, a melhor coisa a ser feita, na minha opinião, era converter esses índices:
Agora a função já pode incrementar os índices para fazer as combinações. Como parâmetros, ela recebe a string que vai ser concatenada, o array com os termos e o índice atual. Se o índice atual foi maior ou igual ao total de termos, a função concatena com a string já gerada anteriormente e inicia uma nova linha.
A chamada da função ficou assim:
Começamos com a string de concatenação, passando o array $combinar (formatamos os índices do $opcoes nele) e o índice 0.
Já o retorno ficou assim:
Cada combinação é uma nova linha na string e as opções da mesma estão separadas por ‘##’. Como preciso dos dados em um novo array (para montar uma tabela, ou uma lista, por exemplo), após a execução da função tratamos o retorno:
Pra quem não conhece, com a constante PREG_SPLIT_NO_EMPTY, a função preg_split não retorna registros vazios no array.
Segue o código completo:
Fica aí o desafio pra quem quiser dar uma melhorada nesse código - quando eu tiver tempo vou trabalhar nele. O ideal seria a função combinacao() retorna já um array certinho, sem utilizar globais. Outra feature legal seria aceitar arrays nos registros do nosso array principal.
Espero que este post ajude alguém com o mesmo problema e até a próxima!
Função para PHP 5.3+
O leitor João Batista Neto enviou a seguinte função, utilizando o recurso de funções anônimas (closures) disponível na versão 5.3 do PHP. Muito bacana a implementação.