If a problem i try to solve now some hours, but simply cant find a solution.
If a single array of paths
$singleArray = array(
'/Web',
'/Web/Test1',
'/Web/Test2',
'/Web/Test2/Subfolder',
'/Web/Test3',
'/Public'
);
From that array i want to create a mulitdimensional array, which keeps the keys but put subfolders in the correct parent folders. Later i want to loop over the new array to create a folder tree (but thats not a problem)
The new array should look like this:
$multiArray = array(
'/Web'=>array(
'/Web/Test1'=>array(),
'/Web/Test2'=>array(
'/Web/Test2/Subfolder'=>array()
),
'/Web/Test3'=>array()
),
'/Public'=>array()
);
The code below will make the array you want. The key to solve your problem is to create a reference to the array every iteration.
<?php
$singleArray = array(
'/Web',
'/Web/Test1',
'/Web/Test2',
'/Web/Test2/Subfolder',
'/Web/Test3',
'/Public'
);
$multiArray = array();
foreach ($singleArray as $path) {
$parts = explode('/', trim($path, '/'));
$section = &$multiArray;
$sectionName = '';
foreach ($parts as $part) {
$sectionName .= '/' . $part;
if (array_key_exists($sectionName, $section) === false) {
$section[$sectionName] = array();
}
$section = &$section[$sectionName];
}
}
Got this working! Great challenge!
First I sort the array by number of folders, so that the first to be processed are those with fewest folders (in the root).
Then the function iterates through each of the array items and each folder in that item, comparing it to the existing items in the array and, if it exists, placing it inside of that item as a multidimensional array.
This will work for up to two subfolders - /root/sub1/sub2 - but it's quite straightforward so simple to add functionality for deeper use.
This sample code also prints out the before/after arrays:
$singleArray = array(
'/Web',
'/Web/Test1',
'/Web/Test2',
'/Web/Test2/Subfolder',
'/Web/Test3',
'/Public'
);
echo "<pre>";
print_r($singleArray);
$multiArray = array();
//first sort array by how many folders there are so that root folders are processed first
usort($singleArray, function($a, $b) {
$a_folders = explode("/", $a);
$b_folders = explode("/", $b);
$a_num = count($a_folders); //number of folders in first
$b_num = count($b_folders); //number of folders in second
if($a_num > $b_num) return -1;
elseif($a_num < $b_num) return 1;
else return 0;
});
//foreach in array
foreach($singleArray as $item){
//get names of folders
$folders = explode("/", $item);
//if the first folder exists
if(in_array($folders[0], $multiArray)){
$key1 = array_search($folders[0], $multiArray);
//repeat for subfolder #1
if(in_array($folders[1], $multiArray[$key1])){
$key2 = array_search($folders[1], $multiArray[$key1]);
//repeat for subfolder #2
if(in_array($folders[2], $multiArray[$key1][$key2])){
$key3 = array_search($folders[2], $multiArray[$key1][$key2]);
array_push($multiArray[$key1][$key2][$key3], $item);
} else array_push($multiArray[$key1][$key2], $item);
} else array_push($multiArray[$key1], $item);
} else array_push($multiArray, $item);
}
//reverse the array so that it looks nice
$multiArray = array_reverse($multiArray);
print_r($multiArray);
This will output:
Array
(
[0] => /Web
[1] => /Web/Test1
[2] => /Web/Test2
[3] => /Web/Test2/Subfolder
[4] => /Web/Test3
[5] => /Public
)
Array
(
[0] => /Web
[1] => /Public
[2] => /Web/Test1
[3] => /Web/Test2
[4] => /Web/Test3
[5] => /Web/Test2/Subfolder
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With