将关键路径字符串的平面数组转换为以空数组结尾的多维数组

问题描述 投票:0回答:2

如果是单个路径数组

$singleArray = array(
   '/Web',
   '/Web/Test1',
   '/Web/Test2', 
   '/Web/Test2/Subfolder',
   '/Web/Test3',
   '/Public'
);

我想从该数组创建一个多维数组,它保留键,但在正确的父文件夹中创建子文件夹。后来,我想循环新数组来创建文件夹树(但这不是问题)。

新数组应如下所示:

$multiArray = array(
   '/Web'=>array(
      '/Web/Test1'=>array(),
      '/Web/Test2'=>array(
          '/Web/Test2/Subfolder'=>array()
      ),
      '/Web/Test3'=>array()
   ),
   '/Public'=>array()
);
php arrays multidimensional-array keypaths
2个回答
5
投票

下面的代码将创建您想要的数组。解决问题的关键是在每次迭代时创建对数组的引用。

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

1
投票

成功了!伟大的挑战!

首先,我按文件夹数量对数组进行排序,以便第一个处理的是文件夹最少的文件夹(在根目录中)。

然后,该函数迭代每个数组项以及该项中的每个文件夹,将其与数组中的现有项进行比较,如果存在,则将其作为多维数组放置在该项内。

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

此示例代码还打印出之前/之后的数组:

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

这将输出:

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
)
© www.soinside.com 2019 - 2024. All rights reserved.