2009-10-22 4 views
1

Хорошо, в основном, я сформировал запрос mySQL, который возвращает набор данных, полностью отсортированный по моей структуре данных. Если бы я должен был объявить, что это будет выглядеть примерно так:PHP> Форма многомерного массива из плоского массива вложенных моделей

$arr = array(
     array('name' => 'Root', 'depth' => 0), 
     array('name' => 'Food', 'depth' => 0), 
     array('name' => 'Fruit', 'depth' => 1), 
     array('name' => 'Bannnanna', 'depth' => 2), 
     array('name' => 'Apple', 'depth' => 2), 
     array('name' => 'Bannnanna', 'depth' => 2), 
     array('name' => 'Meat', 'depth' => 1), 
     array('name' => 'Furniture', 'depth' => 0) 
     ); 

То, что я хочу, чтобы кормить эту $ обр в метод, так что я могу затем получить многомерный массив обратно.

Например, Фрукты были бы ребенком Пищи. И Бананана была бы ребенком Фрута. Мне нужны ключи каждого «ребенка», чтобы быть «страницами».

Массив, который я показал выше, может также возвращать другую информацию, такую ​​как 'lft' и 'rgt'. У меня нет «parentId», но я могу изменить свою модель, если это необходимо, но я бы предпочел придерживаться модели Nested Set.

ответ

4

Следующий код предполагает, что порядок и глубину ваших ценностей являются правильными. Обратите внимание, что он удаляет дубликаты с помощью клавиш.

header('Content-Type: text/plain'); 

$arr = array(
    array('name' => 'Root', 'depth' => 0), 
    array('name' => 'Food', 'depth' => 0), 
    array('name' => 'Fruit', 'depth' => 1), 
    array('name' => 'Bannnanna', 'depth' => 2), 
    array('name' => 'Apple', 'depth' => 2), 
    array('name' => 'Bannnanna', 'depth' => 2), 
    array('name' => 'Meat', 'depth' => 1), 
    array('name' => 'Furniture', 'depth' => 0) 
); 

function process(&$arr, &$prev_sub = null, $cur_depth = 0) { 
    $cur_sub = array(); 
    while($line = current($arr)) { 
    if($line['depth'] < $cur_depth) { 
    return $cur_sub; 
    } elseif($line['depth'] > $cur_depth) { 
    $prev_sub = process($arr, $cur_sub, $cur_depth + 1); 
    } else { 
    $cur_sub[$line['name']] = $line['name']; 
    $prev_sub =& $cur_sub[$line['name']]; 
    next($arr); 
    } 
    } 
    return $cur_sub; 
} 

$values = process($arr); 
print_r($values); 

Выход:

Array 
(
    [Root] => Root 
    [Food] => Array 
     (
      [Fruit] => Array 
       (
        [Bannnanna] => Bannnanna 
        [Apple] => Apple 
       ) 
      [Meat] => Meat 
     ) 
    [Furniture] => Furniture 
) 
+0

Это именно то, что я искал, отлично работает! Можете ли вы опубликовать, как добавить дополнительные поля? – dzm

5

что-то вроде этого, может быть,

  $arr = array(
        array('name' => 'Root', 'depth' => 0), 
        array('name' => 'Food', 'depth' => 0), 
        array('name' => 'Fruit', 'depth' => 1), 
        array('name' => 'Bannnanna', 'depth' => 2), 
        array('name' => 'Apple', 'depth' => 2), 
        array('name' => 'Bannnanna', 'depth' => 2), 
        array('name' => 'Meat', 'depth' => 1), 
        array('name' => 'Furniture', 'depth' => 0) 
        ); 

      $p = array(array()); 
      foreach($arr as $n => $a) { 
       $d = $a['depth'] + 1; 
       $p[$d - 1]['children'][] = &$arr[$n]; 
       $p[$d] = &$arr[$n]; 
      } 

      print_r($p[0]); 
+0

Пожалуйста, не могли бы вы объяснить код Еогеасп как я действительно не могу понять, как возвращение к справочникам! Спасибо – 2011-05-09 21:39:35

+0

@Laykes, Что вы изменили? – mattalxndr

+0

Извините mattalexx: Я даже не могу больше задавать этот вопрос. – Layke

Смежные вопросы