dongling0519 2017-04-19 17:16
浏览 88
已采纳

PHP多维关联数组转换(URL文件夹结构为分层数组)

I'm twisting my brain trying to convert a multi-dimensional associative array into a multi-dimensional non-associative one and got to the point where I decided to seek help..

The whole story:

A. I've got a set of URLs and their KPIs (with an arbitrary folder depth):

URL, Visits

  1. www.example.com
  2. www.example.com/resource1, 100
  3. www.example.com/folderA/resource2, 200
  4. www.example.com/folderA/resource3, 300
  5. www.example.com/folderB/resource4, 400

B. With help of StackOverflow (and surprisingly few lines of PHP -> see here) I was able to transform this into a hierarchical array, representing the URL-structure as folders:

Array
(
[www.example.com] => Array
    (
        [folderA] => Array
            (
                [resource2] => Array
                    (
                        [visits] => 200
                    )

                [resource3] => Array
                    (
                        [visits] => 300
                    )

            )

        [folderB] => Array
            (
                [resource4] => Array
                    (
                        [visits] => 400
                    )

            )

        [resource1] => Array
            (
                [visits] => 100
            )

    )

 )

C. Now, however, I need to get this array into the following structure (children must be non-associative arrays) which is a real brain twister to me...

Array
(
[name] => www.example.com
[isFolder] => 1
[children] => Array
    (
        [0] => Array
            (
                [name] => folderA
                [isFolder] => 1
                [children] => Array
                    (
                        [0] => Array
                            (
                                [name] => resource2
                                [isFolder] => 0
                                [kpis] => Array
                                    (
                                        [visits] => 200
                                    )

                                [children] => Array
                                    (
                                    )

                            )

                        [1] => Array
                            (
                                [name] => resource3
                                [isFolder] => 0
                                [kpis] => Array
                                    (
                                        [visits] => 300
                                    )

                                [children] => Array
                                    (
                                    )

                            )

                    )

            )

        [1] => Array
            (
                [name] => folderB
                [isFolder] => 1
                [children] => Array
                    (
                        [0] => Array
                            (
                                [name] => resource4
                                [isFolder] => 0
                                [kpis] => Array
                                    (
                                        [visits] => 400
                                    )

                                [children] => Array
                                    (
                                    )

                            )

                    )

            )

        [2] => Array
            (
                [name] => resource1
                [isFolder] => 0
                [kpis] => Array
                    (
                        [visits] => 100
                    )

                [children] => Array
                    (
                    )

            )

    )

)

Can anyone help with an approach how to achieve this? Either by transforming the array from step B. or starting from scratch with the original URLs from step A... Any help is greatly appreciated! Thanks a lot!

  • 写回答

1条回答 默认 最新

  • doutong4088 2017-04-19 18:26
    关注

    Below is a little function that will do just what you want. It uses a reference that is moved through the tree and adds data to the array referenced by that reference where necessary.

    I hope the comments give enough explanation of what the code does.

    $sourceArray = [
        'www.example.com' => 0,
        'www.example.com/resource1' => 100,
        'www.example.com/folderA/resource2' => 200,
        'www.example.com/folderA/resource3' => 300,
        'www.example.com/folderB/resource4' => 400,
    ];
    
    function convertToStructure($sourceArray)
    {
        // Initialize the tree
        $tree = [
            'name' => 'root',
            'isFolder' => 1,
            'children' => [],
        ];
    
        // Do nothing if sourceArray is not an array
        if(!is_array($sourceArray)){
            return $tree;
        }
    
        // Loop through the source array
        foreach($sourceArray as $path => $visits){
            // Get a reference to the target tree
            $treeReference = &$tree;
    
            // Split the path into pieces
            $path = explode('/', $path);
    
            // For each piece:
            foreach($path as $key => $name){
                // Get the childKey if the child already exists
                $childKey = findChild($treeReference, $name);
    
                // Create a new child otherwise
                if ($childKey === false) {
                    $treeReference['children'][] = [
                        'name' => $name,
                        'isFolder' => 0,
                        'children' => [],
                    ];
    
                    // Get the key of the new child item
                    end($treeReference['children']);
                    $childKey = key($treeReference['children']);
                }
    
                // Change the reference to the correct child item.
                $treeReference = &$treeReference['children'][$childKey];
    
                // Set isFolder if necessary
                $isFolder = ($key == count($path) - 1 ? 0 : 1);
                if(!empty($isFolder)){
                    $treeReference['isFolder'] = $isFolder;
                }
    
                // Set visits if necessary
                if(!empty($visits)){
                    $treeReference['isFolder'] = ['kpis' => ['visits' => $visits]];
                }
            }
        }
    
        return $tree;
    }
    
    function findChild($tree, $name)
    {
        if(empty($tree['children'])){
            return false;
        }
    
        foreach($tree['children'] as $key => $child){
            if($child['name'] == $name){
                return $key;
            }
        }
        return false;
    }
    
    $treeStructure = convertToStructure($sourceArray);
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 用matlab 设计一个不动点迭代法求解非线性方程组的代码
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试