There is an array of data obtained by Rest API. I am trying to make a menu from this data, but for this I need to convert it taking into account nesting (I think this is done in a loop)

I rummaged through the Internet, everywhere recursion with ordinary numeric id, and my id is a string, I tried to do it myself through foreach, it turned out

foreach ($elements as $item){ $thisRef = &$ref[$item['objectId']]; $thisRef['parent'] = &$item['parent']; $thisRef['name'] = $item['property']['ru']['value']; $thisRef['objectId'] = $item['objectId']; $thisRef['number'] = $item['number']; $thisRef['duration'] = $item['duration']; $thisRef['object'] = $item['object']; $thisRef['listorder'] = $item['listorder']; if($item['parent'] == 0) { $items[$item['objectId']] = &$thisRef; } else { $ref[$item['parent']]['child'][$item['objectId']] = &$thisRef; } } print_r($items); 

The cycle written by me works poorly, it displays a branch only up to level 2

array of elements $ spread below in print_r and var_export

[objectId] is the id of the element

[parent] is the parent of the element, it refers to the parent's objectId, if it is empty or equal to 0, then it has no parent

A big request to offer a solution with unlimited nesting.

I wish you well to help me.

Array through print_r

  Array ( [0] => Array ( [parent] => D0384DBB-F67C-FE92-FF46-F192B3F83B00 [created] => 1540568545112 [element_id] => [ownerId] => [type] => [duration] => [number] => 1 [start_time] => [enable] => [tiam] => [listorder] => 1 [quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00 [updated] => 1540569546246 [value] => [objectId] => 0DE56A96-9FA9-64E0-FFAB-97A246517200 [object] => round [___class] => Elements [property] => Array ( [ru] => Array ( [language_code] => ru [created] => 1540568545865 [lang_id] => 0E5BD427-7883-903C-FFDD-2309E2D79800 [element_id] => 0DE56A96-9FA9-64E0-FFAB-97A246517200 [quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00 [type] => [ownerId] => [value] => Раунд [updated] => [objectId] => C28EE86F-71BC-A6D3-FFF6-707638303500 [object] => round [___class] => Elements_values ) ) ) [1] => Array ( [parent] => [created] => 1540540322673 [element_id] => [ownerId] => [type] => [duration] => [number] => 1 [start_time] => [enable] => [tiam] => [listorder] => 1 [quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00 [updated] => 1540564573693 [value] => [objectId] => 4449513D-1CDD-00EA-FFDF-1947E4FDEA00 [object] => team [___class] => Elements [property] => Array ( [ru] => Array ( [language_code] => ru [created] => 1540540323417 [lang_id] => 0E5BD427-7883-903C-FFDD-2309E2D79800 [element_id] => 4449513D-1CDD-00EA-FFDF-1947E4FDEA00 [quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00 [type] => [ownerId] => [value] => Команда [updated] => [objectId] => 2B2C86CF-E1F8-5D2C-FF0E-1DB592CC7500 [object] => team [___class] => Elements_values ) ) ) [2] => Array ( [parent] => F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00 [created] => 1540567572958 [element_id] => [ownerId] => [type] => [duration] => [number] => 1 [start_time] => [enable] => [tiam] => [listorder] => 1 [quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00 [updated] => 1540567674259 [value] => [objectId] => D0384DBB-F67C-FE92-FF46-F192B3F83B00 [object] => stage [___class] => Elements [property] => Array ( [ru] => Array ( [language_code] => ru [created] => 1540567573722 [lang_id] => 0E5BD427-7883-903C-FFDD-2309E2D79800 [element_id] => D0384DBB-F67C-FE92-FF46-F192B3F83B00 [quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00 [type] => [ownerId] => [value] => Этап [updated] => [objectId] => 4E694471-70B3-C12B-FF79-97895532DD00 [object] => stage [___class] => Elements_values ) ) ) [3] => Array ( [parent] => 4449513D-1CDD-00EA-FFDF-1947E4FDEA00 [created] => 1540565297592 [element_id] => [ownerId] => [type] => [duration] => [number] => 1 [start_time] => [enable] => [tiam] => [listorder] => 1 [quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00 [updated] => 1540565310503 [value] => [objectId] => F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00 [object] => route [___class] => Elements [property] => Array ( [ru] => Array ( [language_code] => ru [created] => 1540565298342 [lang_id] => 0E5BD427-7883-903C-FFDD-2309E2D79800 [element_id] => F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00 [quest_id] => E18A9589-6AB2-8304-FFFC-98C11314CD00 [type] => [ownerId] => [value] => Маршрут [updated] => [objectId] => 9CD62B6E-EACF-2911-FF57-3FF369F2BE00 [object] => route [___class] => Elements_values ) ) ) ) 

Array through var_export

 array ( 0 => array ( 'parent' => 'D0384DBB-F67C-FE92-FF46-F192B3F83B00', 'created' => 1540568545112, 'element_id' => NULL, 'ownerId' => NULL, 'type' => NULL, 'duration' => NULL, 'number' => '1', 'start_time' => NULL, 'enable' => NULL, 'tiam' => NULL, 'listorder' => '1', 'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00', 'updated' => 1540569546246, 'value' => NULL, 'objectId' => '0DE56A96-9FA9-64E0-FFAB-97A246517200', 'object' => 'round', '___class' => 'Elements', 'property' => array ( 'ru' => array ( 'language_code' => 'ru', 'created' => 1540568545865, 'lang_id' => '0E5BD427-7883-903C-FFDD-2309E2D79800', 'element_id' => '0DE56A96-9FA9-64E0-FFAB-97A246517200', 'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00', 'type' => NULL, 'ownerId' => NULL, 'value' => 'Раунд', 'updated' => NULL, 'objectId' => 'C28EE86F-71BC-A6D3-FFF6-707638303500', 'object' => 'round', '___class' => 'Elements_values', ), ), ), 1 => array ( 'parent' => NULL, 'created' => 1540540322673, 'element_id' => NULL, 'ownerId' => NULL, 'type' => NULL, 'duration' => NULL, 'number' => '1', 'start_time' => NULL, 'enable' => NULL, 'tiam' => NULL, 'listorder' => '1', 'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00', 'updated' => 1540564573693, 'value' => NULL, 'objectId' => '4449513D-1CDD-00EA-FFDF-1947E4FDEA00', 'object' => 'team', '___class' => 'Elements', 'property' => array ( 'ru' => array ( 'language_code' => 'ru', 'created' => 1540540323417, 'lang_id' => '0E5BD427-7883-903C-FFDD-2309E2D79800', 'element_id' => '4449513D-1CDD-00EA-FFDF-1947E4FDEA00', 'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00', 'type' => NULL, 'ownerId' => NULL, 'value' => 'Команда', 'updated' => NULL, 'objectId' => '2B2C86CF-E1F8-5D2C-FF0E-1DB592CC7500', 'object' => 'team', '___class' => 'Elements_values', ), ), ), 2 => array ( 'parent' => 'F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00', 'created' => 1540567572958, 'element_id' => NULL, 'ownerId' => NULL, 'type' => NULL, 'duration' => NULL, 'number' => '1', 'start_time' => NULL, 'enable' => NULL, 'tiam' => NULL, 'listorder' => '1', 'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00', 'updated' => 1540567674259, 'value' => NULL, 'objectId' => 'D0384DBB-F67C-FE92-FF46-F192B3F83B00', 'object' => 'stage', '___class' => 'Elements', 'property' => array ( 'ru' => array ( 'language_code' => 'ru', 'created' => 1540567573722, 'lang_id' => '0E5BD427-7883-903C-FFDD-2309E2D79800', 'element_id' => 'D0384DBB-F67C-FE92-FF46-F192B3F83B00', 'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00', 'type' => NULL, 'ownerId' => NULL, 'value' => 'Этап', 'updated' => NULL, 'objectId' => '4E694471-70B3-C12B-FF79-97895532DD00', 'object' => 'stage', '___class' => 'Elements_values', ), ), ), 3 => array ( 'parent' => '4449513D-1CDD-00EA-FFDF-1947E4FDEA00', 'created' => 1540565297592, 'element_id' => NULL, 'ownerId' => NULL, 'type' => NULL, 'duration' => NULL, 'number' => '1', 'start_time' => NULL, 'enable' => NULL, 'tiam' => NULL, 'listorder' => '1', 'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00', 'updated' => 1540565310503, 'value' => NULL, 'objectId' => 'F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00', 'object' => 'route', '___class' => 'Elements', 'property' => array ( 'ru' => array ( 'language_code' => 'ru', 'created' => 1540565298342, 'lang_id' => '0E5BD427-7883-903C-FFDD-2309E2D79800', 'element_id' => 'F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00', 'quest_id' => 'E18A9589-6AB2-8304-FFFC-98C11314CD00', 'type' => NULL, 'ownerId' => NULL, 'value' => 'Маршрут', 'updated' => NULL, 'objectId' => '9CD62B6E-EACF-2911-FF57-3FF369F2BE00', 'object' => 'route', '___class' => 'Elements_values', ), ), ), ) 

At the output, I need something like this:

Array (

  ...... [4449513D-1CDD-00EA-FFDF-1947E4FDEA00] => Array ( [parent] => [name] => Команда [objectId] => 4449513D-1CDD-00EA-FFDF-1947E4FDEA00 [number] => 1 [duration] => [object] => team [listorder] => 1 [child] => Array ( [F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00] => Array ( [parent] => 4449513D-1CDD-00EA-FFDF-1947E4FDEA00 [name] => Маршрут [objectId] => F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00 [number] => 1 [duration] => [object] => route [listorder] => 1 [child]=> Array ( [D0384DBB-F67C-FE92-FF46-F192B3F83B00] => Array ( [parent] => F0BFCFFA-D8F7-B5BE-FF37-D92AE35BBD00 [name] => Этап [objectId] => D0384DBB-F67C-FE92-FF46-F192B3F83B00 [number] => 1 [duration] => [object] => stage [listorder] => 1 ) ) ) ) .... ) ) 
  • Well, use the string id is not a problem - Naumov
  • see my cycle, I tried to do, but the conclusion is limited to level 2 only - Sergey
  • one
    recursion use i. if there is a parent in the parent then start the function again - Naumov
  • one
    "I wish you well for anyone who will help me." +1 - Igor
  • Apparently my knowledge of php is still rather weak, I hope someone can help me .. - Sergey

1 answer 1

Do I understand correctly that the problem is in parent_id connections? It is necessary to bypass the array, and build a multi-level nested menu on it, through parent_id

Yes, the classic version here is recursion. But the problem is that the stack depth in php is usually set to 512 elements, i.e. This is the maximum level of nested recursion, with default settings.

In any case, the settings here are not an option, because theoretically, the nesting depth is not limited, and maybe a million, and a billion, and more - no memory is enough.

But programming is a purely applied thing, and many such moments in programming do not cost theoretically, but elementary physical limitations (usually iron limitations) and common sense: for the menu, 512 levels are with the head, in practice, the menu is usually two-level, rarely three, more already exotic. 10 levels probably never occur anywhere, because Such a menu is already elementary inconvenient - try to climb on this, go crazy.

So the reasonable answer is this: use recursion, and do not bother. Text identifiers do not interfere with building a hierarchy - even html-code can be used as keys, it is a symmetric array, it doesn’t matter.

You can do without recursion, of course, using the do ... while loop, but it will be very expensive, for an array of thousands of elements you will need to iterate over two million elements, for an array of million elements you will need to iterate over two trillion elements, plus the code will be very confusing.

For the menu, this bike is clearly not worth reinventing.

Recursion example https://repl.it/@tomasj/recirsionmenu

  • Thanks for the detailed comment, I couldn’t even make recursion, help, my menu will have no more than 20 elements in the future, I’m not talking about a million. I ask you to help, how to write correctly using the recursion method? - Sergey
  • added the kind of array I need at the output - Sergey
  • Do I understand correctly that the problem is in parent_id connections? It is necessary to bypass the array, and build a multilevel submenu on it, through parent_id ----------------- Yes, you understood correctly, the connection goes by parent - Sergey
  • one
    For example, so repl.it/@tomasj/recirsionmenu - user9289542
  • thank! propose a solution, it is true! - Sergey