PHP> Формирование многомерного массива из плоского массива модели вложенного множества - PullRequest
1 голос
/ 22 октября 2009

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

$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 )
        );

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

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

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

Ответы [ 2 ]

5 голосов
/ 22 октября 2009

как то так может быть

            $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]);
4 голосов
/ 22 октября 2009

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

 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
 )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...