I have a PHP array that looks like this:
Array ( [0] => Array ( [id] => 2 [name] => Item2 [children] => Array ( [0] => Array ( [id] => 1 [name] => Item1 [children] => Array ( [0] => Array ( [id] => 5 [name] => Item5 ) ) ) [1] => Array ( [id] => 4 [name] => Item4 ) ) ) [1] => Array ( [id] => 3 [name] => Item3 ) )
It has unknown (unpredictable) depth and length. Any item on any level may or may not have children. It has been created from an xml file that contains product groups. I would like to convert it to an array that contains arrays of three elements: id, name, and parent id:
[0] => array('id' => '2', 'name' => 'Item2', 'parent' => 0), [1] => array('id' => '1', 'name' => 'Item1', 'parent' => 2), [2] => array('id' => '4', 'name' => 'Item4', 'parent' => 2) etc.
How can I do it? Thank you!
Advertisement
Answer
This can be achieved with a recursive function that pushes all the items from a given level of the array, then calls itself for any children
arrays:
function list_items($array, $parent = 0) { $output = array(); foreach ($array as $arr) { $output[] = array('id' => $arr['id'], 'name' => $arr['name'], 'parent' => $parent); if (is_array($arr['children'] ?? NULL)) { $output = array_merge($output, list_items($arr['children'], $arr['id'])); } } return $output; } $items = list_items($array);
Output (for my slightly expanded data):
Array ( [0] => Array ( [id] => 2 [name] => Item2 [parent] => 0 ) [1] => Array ( [id] => 1 [name] => Item1 [parent] => 2 ) [2] => Array ( [id] => 5 [name] => Item5 [parent] => 1 ) [3] => Array ( [id] => 4 [name] => Item4 [parent] => 2 ) [4] => Array ( [id] => 3 [name] => Item3 [parent] => 0 ) )
Update
It turns out that there is an inconsistency in the array structure; when there is only one child, only the child value is stored rather than a single element array. This can be dealt with by checking the the array to see if the id
(Ид
) element is set, and if it is, pushing the array one level deeper before processing:
function list_items($array, $parent = 0) { $output = array(); if (isset($array['Ид'])) { $array = array($array); } foreach ($array as $arr) { if (!is_array($arr)) echo $arr; $output[] = array('id' => $arr['Ид'], 'name' => $arr['Наименование'], 'parent' => $parent); if (is_array($arr['Группы']['Группа'] ?? NULL)) { $output = array_merge($output, list_items($arr['Группы']['Группа'], $arr['Ид'])); } } return $output; } $items = list_items($array); print_r($items);