【问题标题】:PHP multi-dimensional associative array conversion (URL folder structure as hierarchical array)PHP多维关联数组转换(URL文件夹结构为层次数组)
【发布时间】:2017-04-19 17:16:31
【问题描述】:

我绞尽脑汁试图将一个多维关联数组转换为一个多维非关联数组,结果我决定寻求帮助..

整个故事:

A.我有一组 URL 及其 KPI(具有任意文件夹深度):

网址、访问次数

  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.在 StackOverflow 的帮助下(以及令人惊讶的几行 PHP -> 请参阅 here),我能够将其转换为分层数组,将 URL 结构表示为文件夹:

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.但是,现在我需要将此数组放入以下结构(子数组必须是非关联数组),这对我来说是一个真正的脑筋急转弯......

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

            )

    )

)

任何人都可以提供如何实现这一目标的方法吗?通过转换步骤 B 中的数组或从头开始使用步骤 A 中的原始 URL ... 非常感谢任何帮助! 非常感谢!

【问题讨论】:

    标签: php arrays recursion tree


    【解决方案1】:

    下面是一个小功能,可以满足您的需求。它使用在树中移动的引用,并在必要时将数据添加到该引用所引用的数组中。

    我希望 cmets 对代码的作用给出足够的解释。

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

    【讨论】:

    • 非常好 - 就像一个魅力!非常感谢您提供的合格且有效的示例!
    猜你喜欢
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多