объединить 2 элемента dim-массива в PHP - PullRequest
2 голосов
/ 14 сентября 2011

У меня есть массив $, и я хочу объединить элементы каждого второго уровня следующим образом:

$array['A'] = array('a','b','c');
$array['B'] = array('d','e','f');
$array['C'] = array('g','h','i');

function combine($array)
{
    $result = array();
    foreach($array['A'] as $a)
        {
        foreach($array['B'] as $b)
        {
            foreach($array['C'] as $c)
            {
                $result[] = array($a,$b,$c);
            }
        }
    }
    return $result;
}

Объединение () работает нормально, чтобы показать правильный результат, только если count ($ array) равен 3. Если я добавлю больше элементов $ array, например, $ array ['D'] = array ('j', ' k ',' l '), то это не может работать правильно.

Как я могу решить эту проблему?

Я думаю, что должен использовать рекурсивную функцию. Но у меня не было никакого опыта с этим типом программирования.

Можете ли вы помочь мне? Это сводит меня с ума.

Ответы [ 3 ]

1 голос
/ 14 сентября 2011

Ах, хорошая проблема.Я действительно должен был повторно реализовать это в ряде случаев.Это должно работать для вас:

    class Counter {
    private $bases;
    private $currNum;
    private $increment;
    private $maxVal;

    public function __construct($bases) {
        $this->bases = $bases;
        $this->maxVal = 1;
        $this->currNum = array();
        foreach ($bases as $base) {
            $this->maxVal *= $base;
            $this->currNum[] = 0;
        }
        $this->increment = 0;
    }

    public function increment() {
        ++$this->increment;
        for ($i = count($this->currNum) - 1; $i > -1; --$i) {
            $val = $this->currNum[$i] + 1;
            if ($val >= $this->bases[$i]) {
                $this->currNum[$i] = 0;
            } else {
                $this->currNum[$i] = $val;
                return;
            }
        }
    }

    // TODO handle overflows
    public function hasNext() {
        return $this->increment < $this->maxVal;
    }

    public function getNum() {
        return $this->currNum;
    }

    public function getIncrement() {
        return $this->increment;
    }
}

// your sample arrays
$arrays = array(
array('a', 'b', 'c'),
array('d', 'e', 'f'),
array('g', 'h', 'i')
);

// parameter to counter changes based on how many arrays you have
// if you have 4 arrays of len 4, it'll be $counter = new Counter(array(4,4,4,4));
// it'll work with arrays of varying lengths as well.
// so if you have 1 array of len 2, another of len 3 and a third of len 4:
// $counter = new Counter(array(2,3,4));
$counter = new Counter(array(3,3,3));

$result = array();
while ($counter->hasNext()) {
    $indexes = $counter->getNum();
    //print_r($indexes);
    $result[] = array();
    foreach ($indexes as $arr => $index) {
        $result[count($result) - 1][] = $arrays[$arr][$index];
    }
    $counter->increment();
}

print_r($result);

Я изменил $ array ['A'] $ array ['B'], чтобы он был проиндексирован как $ array [0] $ array [1] и т. Д., Чтобы сделать егос ним проще работать.

counter->getNum()

возвращает индексы массива.Вы можете выбрать, хотите ли вы на самом деле выбрать этот элемент.

0 голосов
/ 14 сентября 2011

Проблема в том, что вашей функции требуется ее аргумент для массива, структурированного так:

Array
(
    [A] => Array()
    [B] => Array()
    [C] => Array()
)

Я полагаю, что добавление еще одной клавиши 'D' на самом деле не нарушает функцию, вы просто не получаете желаемого результата.

0 голосов
/ 14 сентября 2011

Вы можете использовать array_map(null, $array['A'], $array['B'], $array['C'], $array['D']) для этого.

array_map может создать массив массивов, используя null в качестве обратного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...