PHP Create a Multidimensional Array from an array with relational data
json, multidimensional-array, php, recursion
Solution
<?php
header('Content-Type: application/json; charset="utf-8"');
/**
* Helper function
*
* @param array $d flat data, implementing a id/parent id (adjacency list) structure
* @param mixed $r root id, node to return
* @param string $pk parent id index
* @param string $k id index
* @param string $c children index
* @return array
*/
function makeRecursive($d, $r = 0, $pk = 'parent', $k = 'id', $c = 'children') {
$m = array();
foreach ($d as $e) {
isset($m[$e[$pk]]) ?: $m[$e[$pk]] = array();
isset($m[$e[$k]]) ?: $m[$e[$k]] = array();
$m[$e[$pk]][] = array_merge($e, array($c => &$m[$e[$k]]));
}
return $m[$r][0]; // remove [0] if there could be more than one root nodes
}
echo json_encode(makeRecursive(array(
array('id' => 5273, 'parent' => 0, 'name' => 'John Doe'),
array('id' => 6032, 'parent' => 5273, 'name' => 'Sally Smith'),
array('id' => 6034, 'parent' => 6032, 'name' => 'Mike Jones'),
array('id' => 6035, 'parent' => 6034, 'name' => 'Jason Williams'),
array('id' => 6036, 'parent' => 5273, 'name' => 'Sara Johnson'),
array('id' => 6037, 'parent' => 5273, 'name' => 'Dave Wilson'),
array('id' => 6038, 'parent' => 6037, 'name' => 'Amy Martin'),
)));
demo: https://3v4l.org/s2PNC
Problem
Possible Duplicate: Converting an array from one to multi-dimensional based on parent ID values I am working in PHP. I have the following array that has relational data (parent child relationships). ``` Array ( [5273] => Array ( [id] => 5273 [name] => John Doe [parent] => ) [6032] => Array ( [id] => 6032 [name] => Sally Smith [parent] => 5273 ) [6034] => Array ( [id] => 6034 [name] => Mike Jones [parent] => 6032 ) [6035] => Array ( [id] => 6035 [name] => Jason Williams [parent] => 6034 ) [6036] => Array ( [id] => 6036 [name] => Sara Johnson [parent] => 5273 ) [6037] => Array ( [id] => 6037 [name] => Dave Wilson [parent] => 5273 ) [6038] => Array ( [id] => 6038 [name] => Amy Martin [parent] => 6037 ) ) ``` I need it to be in this JSON format: ``` { "id":"5273", "name":"John Doe", "data":{ }, "children":[ { "id":" Sally Smith", "name":"6032", "data":{ }, "children":[ { "id":"6034", "name":"Mike Jones", "data":{ }, "children":[ { "id":"6035", "name":"Jason Williams", "data":{ }, "children":[ { "id":"node46", "name":"4.6", "data":{ }, "children":[ ] } ] } ] }, { "id":"6036", "name":"Sara Johnson", "data":{ }, "children":[ ] }, { "id":"6037", "name":"Dave Wilson", "data":{ }, "children":[ { "id":"6038", "name":"Amy Martin", "data":{ }, "children":[ ] } ] } ] } ] } ``` I know I need to create a multidimensional array and run it through json_encode(). I also believe this method used to do this needs to be recursive because the real world data could have an unknown number of levels. I would be glad to show some of my approaches but they have not worked. Can anyone help me? I was asked to share my work. This is what I have tried but I have not gotten that close to I don't know how helpful it is. I made an array of just the relationships. ``` foreach($array as $k => $v){ $relationships[$v['id']] = $v['parent']; } ``` I think (based off another SO post) used this relational data to create a the new multidimensional array. If I got this to work I was going to work on adding in the correct "children" labels etc. ``` $childrenTable = array(); $data = array(); foreach ($relationships as $n => $p) { //parent was not seen before, put on root if (!array_key_exists($p, $childrenTable)) { $childrenTable[$p] = array(); $data[$p] = &$childrenTable[$p]; } //child was not seen before if (!array_key_exists($n, $childrenTable)) { $childrenTable[$n] = array(); } //root node has a parent after all, relocate if (array_key_exists($n, $data)) { unset($data[$n]); } $childrenTable[$p][$n] = &$childrenTable[$n]; } unset($childrenTable); print_r($data); ```