maestrojed maestrojed - 1 month ago 6
JSON Question

PHP Create a Multidimensional Array from an array with relational data


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

Answer
<?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