首页 > 解决方案 > 合并具有匹配值的多维数组

问题描述

我有一个$list看起来像这样的数组 ifprint_r($list);

Array
(
    [0] => images/announcement
    [1] => images/background
    [2] => images/background/thumbnail
    [3] => images/character
    [4] => images/character/frame
    [5] => images/character/party
    [6] => images/particle
    [7] => images/story/background
    [8] => images/story/character/1016/face
    [9] => images/unit/thumbnail
    [10] => images/user_title/background
    [11] => ss/chapter_background
    [12] => ss/others/ability_board_s
    [13] => ss/others/common/back-light-2
    [14] => ss/others/common/back_light_s

这是我想要实现的结果数组结构(在 JSON 中)(请注意,最外面的文件夹files是固定的):

{
   "name":"files",
   "type":"folder",
   "path":"files",
   "items":[
      {
         "name":"images",
         "type":"folder",
         "path":"files\/images",
         "items":[
                     "name":"announcement",
                     "type":"folder",
                     "path":"files\/images\/announcement",
                     "items":[]
         ]
      },
      {
         "name":"ss",
         "type":"folder",
         "path":"files\/ss",
         "items":[
                     "name":"others",
                     "type":"folder",
                     "path":"files\/ss\/others",
                     "items":[
                                 "name":"sub",
                                 "type":"folder",
                                 "path":"files\/ss\/sub",
                                 "items":[]
                             ]
         ]
      },
      {
         "name":"sound",
         "type":"folder",
         "path":"files\/sound",
         "items":[

         ]
      },
      {
         "name":"New folder (4)",
         "type":"folder",
         "path":"files\/New folder (4)",
         "items":[

         ]
      },
      {
         "name":"New folder (5)",
         "type":"folder",
         "path":"files\/New folder (5)",
         "items":[

         ]
      },
      {
         "name":"New folder (6)",
         "type":"folder",
         "path":"files\/New folder (6)",
         "items":[

         ]
      }
   ]
}

通过一些代码,我能够将每个$list字符串拆分为多维数组:

function explodeToNestedArray($delimiter, $key, $dir)
    { 
        $value = array();
        $keys = explode($delimiter, $key, 2);

        $value["name"]=$keys[0];
        $value["type"]= "folder";
        $value["path"]= $dir . "/" . $keys[0];
        if ($keys[1] == null) $value["items"] = array();
        else
        $value["items"] = explodeToNestedArray("/", $keys[1], $dir . "/" . $keys[0]);
        return $value;
    }
  $list2 = array();
  foreach ($list as $value) {
    $list2[] = explodeToNestedArray("/", $value, "");
  }
      print_r($list2);

结果$list2如下所示:

Array
(
    [0] => Array
        (
            [name] => images
            [type] => folder
            [path] => /images
            [items] => Array
                (
                    [name] => announcement
                    [type] => folder
                    [path] => /images/announcement
                    [items] => Array
                        (
                        )

                )

        )

    [1] => Array
        (
            [name] => images
            [type] => folder
            [path] => /images
            [items] => Array
                (
                    [name] => background
                    [type] => folder
                    [path] => /images/background
                    [items] => Array
                        (
                        )

                )

        )

    [2] => Array
        (
            [name] => images
            [type] => folder
            [path] => /images
            [items] => Array
                (
                    [name] => background
                    [type] => folder
                    [path] => /images/background
                    [items] => Array
                        (
                            [name] => thumbnail
                            [type] => folder
                            [path] => /images/background/thumbnail
                            [items] => Array
                                (
                                )

                        )

                )

        )

    [3] => Array
        (
            [name] => images
            [type] => folder
            [path] => /images
            [items] => Array
                (
                    [name] => character
                    [type] => folder
                    [path] => /images/character
                    [items] => Array
                        (
                        )

                )

        )

    [4] => Array
        (
            [name] => images
            [type] => folder
            [path] => /images
            [items] => Array
                (
                    [name] => character
                    [type] => folder
                    [path] => /images/character
                    [items] => Array
                        (
                            [name] => frame
                            [type] => folder
                            [path] => /images/character/frame
                            [items] => Array
                                (
                                )

                        )

                )

        )

    [5] => Array
        (
            [name] => images
            [type] => folder
            [path] => /images
            [items] => Array
                (
                    [name] => character
                    [type] => folder
                    [path] => /images/character
                    [items] => Array
                        (
                            [name] => party
                            [type] => folder
                            [path] => /images/character/party
                            [items] => Array
                                (
                                )

                        )

                )

        )
..........etc*
)


$list2如果它们具有相同的子数组 [“item”] 元素,我该如何合并它们,["name"] = foldername以便我可以得到想要的结果?使用array_merge_recursive();最终将所有子数组分成不同的类型、名称、路径和项目数组。

标签: phparrays

解决方案


我认为这会做你想要的。它遍历列表的每个元素,在输出数组的列表元素中查找每个键。如果没有找到,它会在输出中创建一个新条目;如果找到了,那么我们继续沿着树向下确定在哪里添加键的下部。请注意,对于叶元素,我们添加 a typeof file,如果您希望它folder只是删除该行上的条件(即$element['type'] = 'folder';)。

$output = array('name' => 'files', 'type' => 'folder', 'path' => 'files', 'items' => array());

function explodeToNestedArray($delimiter, $key, &$output) {
    $keys = explode($delimiter, $key, 2);
    if (($k = array_search($keys[0], array_column($output['items'], 'name'))) === false) {
        // need to create an element
        $element = array('name' => $keys[0], 'path' => $output['path'] . "/{$keys[0]}", 'items' => array());
        $element['type'] = (count($keys) == 1) ? 'file' : 'folder';
        if (count($keys) == 2) explodeToNestedArray($delimiter, $keys[1], $element);
        $output['items'][] = $element;
    }
    else {
        // any children to add?
        if (count($keys) == 2) {
            explodeToNestedArray($delimiter, $keys[1], $output['items'][$k]);
            // change the type to folder in case it was previously a leaf
            $output['items'][$k]['type'] = 'folder';
        }
    }
}

foreach ($list as $node) {
    explodeToNestedArray('/', $node, $output);
}

输出太长,无法在此处显示,但您可以在 3v4l.org 上的此演示中看到它。


推荐阅读