Упростите и абстрагируйте мой код: объединение строк - PullRequest
1 голос
/ 05 февраля 2012

Я хочу объединить строки в PHP.Мой сценарий создает каждую возможную комбинацию, как показано ниже.

$part1 = array('','d','n','s','g');
$part2 = array('a','e','o','oo');
$part3 = array('m','n','s','d','l','t','g','j','p');
$part4 = array('g','p','l','');
$part5 = array('g','p','l');
$part6 = array('a','e','o');
$part7 = array('d','l','r','');

$names = array();

foreach ($part1 as $letter1) {
    foreach ($part2 as $letter2) {
        foreach ($part3 as $letter3) {
            foreach ($part4 as $letter4) {
                foreach ($part5 as $letter5) {
                    foreach ($part6 as $letter6) {
                        foreach ($part7 as $letter7) {
                            $names[] = $letter1 . $letter2 . $letter3 . $letter4 . $letter5 . $letter6 . $letter7;
                        }
                    }
                }
            }
        }
    }
}

Но я не доволен своим решением.Я быстрый и грязный код.Есть ли решение, которое работает с гибким количеством массивов деталей, поэтому я могу расширить скрипт, например, $part8 easyiely?(без изменения конструкции петли)

Ответы [ 2 ]

4 голосов
/ 05 февраля 2012

Рекурсивный:

function buildNames( $parts, $chars = ''){
  // Nothing to do, shouldn't happen
  if( !count( $parts)){
    return array();
  }

  $names = array();
  $part = array_shift( $parts);
  // Max level, we can build final names from characters
  if( !count( $parts)){
     foreach( $part as $char){
        $names[] = $chars . $char;
     }
     return $names;
  }

  // "We need to go deeper" and build one more level with remembered chars so far
  foreach( $part as $char){
     $names = array_merge( $names, buildNames( $parts, $chars . $char));
  }

  return $names;
}

$parts = array( $part1, $part2, $part3, $part4, $part5, $part6, $part7);
$names = buildNames( $parts);

С головы, с нуля, если что-то комментирует, но идея должна быть хорошей

1 голос
/ 05 февраля 2012

Вы можете уменьшить эту проблему до шести декартовых произведений:

cartesianProduct($part1, 
  cartesianProduct($part2, 
    cartesianProduct($part3, 
      cartesianProduct($part4, 
        cartesianProduct($part5, 
          cartesianProduct($part6, $part7))))));


function cartesianProduct($p1, $p2) {
   $ret = array();
   foreach($p1 as $l1)
     foreach($p2 as $l2) 
        $ret[] = $l1 . $l2;
   return $ret;
}
...