php - 合并具有匹配值的多维数组
问题描述
我有一个$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();
最终将所有子数组分成不同的类型、名称、路径和项目数组。
解决方案
我认为这会做你想要的。它遍历列表的每个元素,在输出数组的列表元素中查找每个键。如果没有找到,它会在输出中创建一个新条目;如果找到了,那么我们继续沿着树向下确定在哪里添加键的下部。请注意,对于叶元素,我们添加 a type
of 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 上的此演示中看到它。
推荐阅读
- python - Pandas 手动计算方差
- mysql - Laravel 从关系表中获取数据
- ruby-on-rails - 如何在 ruby 中将类方法更改为实例方法?
- asp.net-core - 如何在 asp.net razor 中将 routeValues 传递给 Html.ActionLink
- flutter - 使用flutter windows package url launcher撰写邮件时如何附加文件?
- php - 在 Alpine Linux 中安装特定版本的 PHP
- java - 抽象类的多个子类型和动态转换的通用接口
- bash - Azure Devops 在触发新创建的管道时通过休息问题触发管道
- html - 使用 1 个标记创建 2 个基于断点的布局
- reactjs - 当单击来自 custombodyrender 的操作按钮时,如何防止 onRowClick?