Home > Enterprise >  Building a PHP directory array from directory IDS table
Building a PHP directory array from directory IDS table

Time:10-08

I have a table that contains a directory structure. There is an item ID and a DirectoryID. The DirectoryID refers to an item ID and is, as such, a child directory under the parent directory. An example below:

# ID, DirectoryID, DirectoryName
'1', '0', 'Root Dir'
'2', '0', 'Another Root Dir'
'3', '2', 'TESTING456'
'4', '3', 'TESTING789'
'5', '1', 'TESTINGMORE'
'6', '4', 'RANDOM DIR'

Using PHP, how do I build that into an array that looks like the one below?

$array = [
   [2 => 'Another Root Dir',3 => 'TESTING456', 4 => 'TESTING789', 6 => 'RANDOM DIR'],
   [1 => 'Root Dir',5 => 'TESTINGMORE']
];

CodePudding user response:

Loop through the root nodes and then for each children.

$dirs = [
    ['1', '0', 'Root Dir'],
    ['2', '0', 'Another Root Dir'],
    ['3', '2', 'TESTING456'],
    ['4', '3', 'TESTING789'],
    ['5', '1', 'TESTINGMORE'],
    ['6', '4', 'RANDOM DIR'],
];

$array = [];
foreach (array_filter($dirs, fn($dir) => '0' === $dir[1]) as $root) {
    $parent  = $root[0];
    $current = [$parent => $root[2]];
    while ($children = array_filter($dirs, fn($dir) => $dir[1] === $parent)) {
        $child            = reset($children);
        $parent           = $child[0];
        $current[$parent] = $child[2];
    }
    $array[] = $current;
}

print_r($array);

Output

Array
(
    [0] => Array
        (
            [1] => Root Dir
            [5] => TESTINGMORE
        )

    [1] => Array
        (
            [2] => Another Root Dir
            [3] => TESTING456
            [4] => TESTING789
            [6] => RANDOM DIR
        )

)

CodePudding user response:

If you mean list of all paths for directory array, first create tree then we'll iterate it. I will start with JS because it's more fun.

// ID, DirectoryID, DirectoryName
var arr = [
  ['1', '0', 'Root Dir'],
  ['2', '0', 'Another Root Dir'],
  ['3', '2', 'TESTING456'],
  ['4', '3', 'TESTING789'],
  ['5', '1', 'TESTINGMORE'],
  ['6', '4', 'RANDOM DIR']
]

console.log(do_arr(arr));

function do_arr(arr) {

  // grouping by id for easy access
  var grouped = arr.reduce(function(agg, [id, parent, name]) {
    agg[id] = { id, parent, name }
    return agg;
  }, {})

  // we want 1 root for all others
  grouped['0'] = { id: 0, name: 'really-main-root' }

  // creating tree with children
  arr.forEach(function([id, parent, name]) {
    grouped[parent].children = grouped[parent].children || []
    grouped[parent].children.push(id)
  })

  // doing all_paths
  var result = [];
  function iterate(obj, so_far) {
    if (obj.children) {
      obj.children.forEach(function(child_id) {
        iterate(grouped[child_id], so_far.concat({
          id: child_id,
          name: grouped[child_id].name
        }));
      })
    } else {
      result.push(so_far)
    }
  }
  iterate(grouped[0], [])
  
  return result;
}
.as-console-wrapper {
  max-height: 100% !important
}

And here's the PHP version:


$arr = [
    ['1', '0', 'Root Dir'],
    ['2', '0', 'Another Root Dir'],
    ['3', '2', 'TESTING456'],
    ['4', '3', 'TESTING789'],
    ['5', '1', 'TESTINGMORE'],
    ['6', '4', 'RANDOM DIR'],
];

print_r(do_arr($arr));

function do_arr($arr)
{

    // grouping by id for easy access
    $grouped = array_reduce($arr, function ($agg, $item) {
        $id = $item[0];
        $parent = $item[1];
        $name = $item[2];
        $agg[$id] = compact('id', 'parent', 'name');
        return $agg;
    }, []);

    // we want 1 root for all others
    $grouped['0'] = ['id' => '0'];

    // creating tree with children
    foreach ($grouped as $item) {
        extract($item);
        if (isset($parent)) {
            $grouped[$parent]["children"][] = $id;
        }
    }

    // doing all_paths
    $result = [];
    function iterate($obj, $so_far = [], $grouped, &$result)
    {
        if (isset($obj["children"])) {
            foreach ($obj["children"] as $child_id) {
                if ($child_id) {
                    iterate($grouped[$child_id], array_merge($so_far, [$child_id => $grouped[$child_id]['name']]), $grouped, $result);
                }
            }
        } else {
            $result[] = $so_far;
        }
    }
    iterate($grouped['0'], [], $grouped, $result);
    return $result;
}
  • Related