2013-06-04 6 views
4

Я пытаюсь создать многомерный массив с глубиной, равной количеству совпадений, найденных в регулярном выражении. Ключи массива должны быть строковым значением для каждого совпадения.Динамически создавать многомерный массив

Например:

preg_match('/([A-Z])\-?([0-9])\-?([0-9]{1,3})/i', 'A-1-001', $matches); 

Возвращает:

Array (
    [0] => A-1-001 
    [1] => A 
    [2] => 1 
    [3] => 001 
) 

Что я хочу, чтобы преобразовать в:

$foo = array(
    'A' => array(
     '1' => array(
      '001' => array('some', 'information') 
     ) 
    ) 
); 

Так что я могу объединить его с другим многомерным массивом, как это:

$bar['A']['1']['001'] = array('some', 'other', 'information'); 

Процесс должен обрабатывать любое количество совпадений/размеров.


Ниже приводится мой нынешний подход. Я не понимаю концепцию, потому что эта попытка отстает от моей цели.

$foo = array(); 
$j = count($matches); 

for ($i = 1; $i < $j; $i++) { 
    $foo[ $matches[$i - 1] ] = $matches[$i]; 
} 

/* 
    $foo's structure becomes: 
    Array (
     [A-1-001] => A 
     [A] => 1 
     [1] => 001 
) 
*/ 

Это только замена ключей массива, а не создание новых дочерних массивов, которые мне нужны.


Любые предложения или решения были бы высоко оценены. Благодаря!

ответ

2

С некоторыми PHP-Fu:

$matches = array('A-1-001', 'A', 1, '001'); 
$info = array('some', 'information'); 
print_r(tree($matches, $info)); 

function tree($array, $info){ 
    $max = count($array)-1; 
    $result = array($array[$max] => $info); 
    for($i=$max-1;$i>0;$result = array($array[$i--] => $result)); 
    return $result; 
} 

Выход:

Array 
(
    [A] => Array 
     (
      [1] => Array 
       (
        [001] => Array 
         (
          [0] => some 
          [1] => information 
         ) 

       ) 

     ) 

) 
+0

Это все жизнеспособные варианты, хотя мой профайлер говорит функция Хамзы немного быстрее выполняется. Спасибо за вашу помощь всем! – Jason

1

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

И тогда мы можем все установить. Таким образом, код будет что-то, как следует

$foo = array(); 
$reversed = array_reverse($matches); 
$some_info_array = array('some', 'information'); 

foreach($reversed as $key) { 
    if(empty($foo)) { 
     $foo[$key] = $some_info_array; 
    } else { 
     $foo[$key] = $foo; 
    } 
} 

код не проверял, но должно дать вам Nive идею/старт

1

Учитывая исходный массив:

$original_array = array('A-1-001', 'A', '1', '001'); 

Вы можете преобразовать его в формат, который вы описали следующим образом:

$new_array[ $original_array[1] ] = array($original_array[2] => $original_array[3]); 

Это дает

array(1) { 
    ["A"]=> 
    array(1) { 
    [1]=> 
    string(3) "001" 
    } 
} 

Вы можете присвоить значения этого массива, как вы указали:

$new_array['A']['1']['001'] = array('some', 'information'); 
1

Вы можете использовать такую ​​функцию ... она должна покрывать любую глубину.Бонус в том, что вы можете продолжать передавать значение $ tree в большее количество филиалов и получать одно дерево с несколькими продуктами.

function arrayToTree($array, &$tree, $addlAttribs){ 
    $node = array_shift($array); 
    if (count($array)){ 
     // this is a branch 
     $tree[$node] = array(); 
     return arrayToTree($array, $tree[$node]); 
    } else { 
     $tree[$node] = $addlAttribs; 
     return; 
    } 
} 

Вы бы использовать его как

$t = array(); 
array_shift($matches); // remove the first match "A-1-001" 
arrayToTree($matches, $tree, $productInfo); 
print_r($tree); 
Смежные вопросы