@dom12

Как построить древовидный массив по уровню?

Как построить древовидный массив по уровню, я пытался самостоятельно написать функцию, но на 2 ур. (и т.д.) добавляются дочерние массивы от предыдущего родителя 1 ур. (и т.д.).
function createTree($MENU,$LEVEL=0,$INDEX=0){
$Result = array();
foreach($MENU as $I=>$ITEM){
if ($LEVEL == $ITEM["LEVEL"]){
$NEXT = $I+1;
if($NEXT<=$INDEX) continue;
if(array_key_exists($NEXT, $MENU) && $ITEM["LEVEL"] < $MENU[$NEXT]["LEVEL"]){
$ITEM['CHILDREN'] = createTree($MENU,$MENU[$NEXT]["LEVEL"],$I);
}
$Result[] = $ITEM;
if($MENU[$NEXT]["LEVEL"]<$ITEM["LEVEL"]) break;
}
} 
return $Result;
}
echo print_r(createTree($arMenu),true);

Массив переменной $arMenu:
spoiler
Array(
    Array(
		[LEVEL] => 1,
		[NAME] => Спецодежда
	),
	Array(
		[LEVEL] => 2,
		[NAME] => Антистатическая одежда
	),
	Array(
		[LEVEL] => 3,
		[NAME] => Халаты
	),
	Array(
		[LEVEL] => 3,
		[NAME] => Костюмы

	),         
	Array(
		[LEVEL] => 2,
		[NAME] => Одежда для чистых помещений
	),
	Array(
		[LEVEL] => 3,
		[NAME] => Халаты
	),
    Array(
		[LEVEL] => 3,
		[NAME] => Обувь технологическая
	),
	Array(
		[LEVEL] => 2,
		[NAME] => Перчатки
	),
    Array(
		[LEVEL] => 2,
		[NAME] => Технологические принадлежности
	),
	Array(
		[LEVEL] => 1,
		[NAME] => Спецобувь
	),
    Array(
		[LEVEL] => 1,
		[NAME] => Испытательное оборудование
	),
	Array(
		[LEVEL] => 2,
		[NAME] => Халаты
	),
	Array(
		[LEVEL] => 3,
		[NAME] => Халаты
	),
	Array(
		[LEVEL] => 3,
		[NAME] => Костюмы

	),
	Array(
		[LEVEL] => 2,
		[NAME] => Обувь технологическая
	)
)

Должно получиться:
spoiler
Array(
    Array(
		[LEVEL] => 1,
		[NAME] => Спецодежда
		[CHILDREN] => Array(
			Array(
				[LEVEL] => 2,
				[NAME] => Антистатическая одежда,
				[CHILDREN] => Array(
					Array(
						[LEVEL] => 3,
						[NAME] => Халаты
					),
					Array(
						[LEVEL] => 3,
						[NAME] => Костюмы

					)
				)
			),
			Array(
				[LEVEL] => 2,
				[NAME] => Антистатическая одежда,
				[CHILDREN] => Array(
					Array(
						[LEVEL] => 3,
						[NAME] => Халаты
					),
					Array(
						[LEVEL] => 3,
						[NAME] => Костюмы
					),
				)
			),
			Array(
				[LEVEL] => 2,
				[NAME] => Одежда для чистых помещений,
				[CHILDREN] => Array(
					Array(
						[LEVEL] => 3,
						[NAME] => Халаты
					),
					Array(
						[LEVEL] => 3,
						[NAME] => Обувь технологическая
					)
				)
			),
			Array(
				[LEVEL] => 2,
				[NAME] => Перчатки
			),
			Array(
				[LEVEL] => 2,
				[NAME] => Технологические принадлежности
			),
		)
	),
	Array(
		[LEVEL] => 1,
		[NAME] => Спецобувь
	),
    Array(
		[LEVEL] => 1,
		[NAME] => Испытательное оборудование,
		[CHILDREN] => Array(
			Array(
				[LEVEL] => 2,
				[NAME] => Халаты
				[CHILDREN] => Array(
					Array(
						[LEVEL] => 3,
						[NAME] => Халаты
					),
					Array(
						[LEVEL] => 3,
						[NAME] => Костюмы

					),
				)
			),
			Array(
				[LEVEL] => 2,
				[NAME] => Обувь технологическая
			)
		)
	)
)
  • Вопрос задан
  • 175 просмотров
Решения вопроса 1
0xD34F
@0xD34F
function createTree($data, $params = []) {
  extract($params + [
    'levelKey' => 'level',
    'childrenKey' => 'children',
  ]);

  $root = [];

  foreach ($data as $n) {
    $arr = &$root;

    for (
      $level = $data[0][$levelKey];
      $level++ < $n[$levelKey];
      $arr = &$arr[count($arr) - 1][$childrenKey]
    ) ;

    $arr[] = $n + [ $childrenKey => [] ];
  }

  return $root;
}


$tree = createTree($arMenu, [ 'levelKey' => 'LEVEL' ]);

или

function createTree($data, $params = []) {
  $levelKey = $params['levelKey'] ?? 'level';
  $childrenKey = $params['childrenKey'] ?? 'children';

  $root = [];
  $stack = [ [ $data[0][$levelKey], &$root ] ];

  foreach ($data as $n) {
    $end = end($stack);
    $level = $n[$levelKey];

    if ($level > $end[0]) {
      $stack[] = [ $level, &$end[1][count($end[1]) - 1][$childrenKey] ];
    } else while ($level < end($stack)[0]) {
      array_pop($stack);
    }

    end($stack)[1][] = array_merge($n, [ $childrenKey => [] ]);
  }

  return $root;
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы