Convert single array to multidimensional array in php

时间:2022-04-16 10:49:37

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

2 个解决方案

#1


5  

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

#2


0  

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.

这将最多可用于两个子文件夹 - / root / sub1 / sub2 - 但它非常简单,添加功能以便更深入地使用。

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
)

#1


5  

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

#2


0  

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.

这将最多可用于两个子文件夹 - / root / sub1 / sub2 - 但它非常简单,添加功能以便更深入地使用。

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
)