0

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']
];

2 Answers 2

1

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
        )

)
Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.