Search code examples
phpobjectrecursionmultidimensional-arrayparent-child

Converting a One-Dimensional Array into a Nested Array Using Relationship Keys


Say I have an array with keys representing id and values representing parent:

4  => 0
2  => 0
5  => 2
6  => 5
8  => 0
9  => 0
10 => 8
12 => 0
13 => 0
14 => 0
18 => 7
19 => 18
20 => 19
21 => 20
22 => 21
23 => 22
24 => 23
28 => 20
7  => 5

You could also read this as an object:

  { 
   id     : 4,
   parent : 0
  } // etc...

The multidimensional array I'd want to achieve from this would be:

4  => 0
2  => 5  
        => 6
        => 7
            => 18
                 => 19
                      => 20
                           => 21
                                 => 22
                                       => 23
                                             => 24
                           => 28
8  => 10
9  => 0
12 => 0
13 => 0
14 => 0

How would I go about doing this?


Solution

  • If you write a little helper function to rework your data to a structure similar to:

    $input = array(
      array('id' => '4', 'parent' => '0'),
      // ...
    );
    

    which could be achieved with something like:

    $data = array_map(function ($entry) {
      list($id, $parent) = array_map('trim', explode('=>', $entry));
      return array(
        'id' => $id,
        'parent' => $parent
      );
    }, explode("\n", $data));
    

    you could then use a function I used in a similar question:

    function flatToNested($d, $r = 0, $p = 'parent', $k = 'id', $c = 'children') {
      $m = array();
      foreach ($d as $e) {
        isset($m[$e[$p]]) ?: $m[$e[$p]] = array();
        isset($m[$e[$k]]) ?: $m[$e[$k]] = array();
        $m[$e[$p]][] = array_merge($e, array($c => &$m[$e[$k]]));
      }
      return $m[$r];
    }
    

    to produce a nested array with:

    $nested = flatToNested($data);
    

    demo: http://codepad.viper-7.com/HAZxaA