php - 类别的递归数组和子类别 PHP
问题描述
我有一系列类别,其中包含许多子类别,每个子类别都有其子类别,依此类推...
array(1) {
["categories"]=>array(11) {
[0]=>array(4) {
["id"]=>int(368)
["name"]=>string(8) "Aksesuar"
["parentId"]=>NULL
["subCategories"]=>array(15) {
[0]=>
array(4) {
["id"]=>
int(387)
["name"]=>
string(4) "Saat"
["parentId"]=>
int(368)
["subCategories"]=>
array(0) {
}
}
[1]=>
array(4) {
["id"]=>
int(394)
["name"]=>
string(6) "Şapka"
["parentId"]=>
int(368)
["subCategories"]=>
array(0) {
}
}
[2]=>
array(4) {
["id"]=>
int(396)
["name"]=>
string(17) "Takı & Mücevher"
["parentId"]=>
int(368)
["subCategories"]=>
array(17) {
[0]=>
array(4) {
["id"]=>
int(397)
["name"]=>
string(8) "Bileklik"
["parentId"]=>
int(396)
["subCategories"]=>
array(7) {
[0]=>
array(4) {
["id"]=>
int(1238)
["name"]=>
string(15) "Altın Bileklik"
["parentId"]=>
int(397)
["subCategories"]=>
array(0) {
}
}
每个子类别都有 parentId 指示父类别,大多数顶级父类别的父 id 为 null。我需要一个递归函数,我会将参数作为子类别的 id 和类别数组提供,它会返回父类别数组及其子类别。
function recursive($needle, $array, $id, $holder = [])
{
$holder = [];
foreach ($array as $key => $value) {
if ($key == $needle && $value == $id) {
$holder = array_merge($holder, $array);
}
if (is_array($value)) {
$holder = array_merge($holder, recursive($needle, $value, $id, $holder));
}
}
return $holder;
}
$res = recursive('id', $categories, 5208);
上面的函数只返回父类别及其子类别的数组。
解决方案
我不完全确定 'holder' 函数变量的用途是什么,因为您在每次调用时将其重置为一个空数组,所以我完全删除了它。
function recursive(string $needle, array $categories, $id): ?array
{
foreach ($categories as $cat) {
if (array_key_exists($needle, $cat) && $cat[$needle] === $id) {
// make sure that if correct category is found,
// no subcategories will be included
unset($cat['subCategories']);
return $cat;
} else {
$subCat = recursive($needle, $cat['subCategories'], $id);
// if the $subCat is not null, it indicates the category
// with the correct id, or one of it's parent has been found
if ($subCat !== null) {
$cat['subCategories'] = $subCat;
return $cat;
}
}
}
return null;
}
实际上并没有那么复杂,如果在其中找到 ID,则该函数返回一个数组,如果它是子项,则返回一个数组,如果没有找到,则返回 NULL。
该函数遍历提供的关卡的类别,并检查当前关卡是否包含提供的 ID。如果没有,它将搜索所有子类别。如果在子类别中找到某些内容,它将用返回的子类别替换当前的子类别,并返回类别本身。
如果您围绕一个类别包装一个类,这可能会更干净,但这应该可以完成工作。如果您还有其他问题,请告诉我。
查看此 3v4l以了解完整的复制案例。
推荐阅读
- android - 房间数据库的类型转换器不起作用
- laravel-fortify - laravel fortify 登录后如何获取用户信息
- javascript - 向对象添加键值
- node.js - 运行 npm run watch 并在 laravel-vue 项目中出现此错误。如何解决?
- http-status-code-500 - 使用管理 API 更新“JSON”类型的 Pulsar 模式时出现 500 错误
- ios - 如何在真正的 Apple Watch 上调试快捷方式意图?
- c# - 我只想在 Xamarin.Forms 不旋转屏幕的情况下获取设备的旋转状态
- java - 在 Spring 自定义查询中找不到类型的属性
- assembly - MASM 相当于 NASM
- go - 从 Apache Beam Go SDK 写入 BigQuery 时类型无效