我已经创建了一个类别树,其中每个类别都包含子类别,每个类别都包含其关联的内容。此树中的某些类别包含子类别,但没有关联的内容。如何清理类别树,以便树结构只包含具有关联内容的类别,或者具有具有关联内容的子类别的类别?也就是说,在类别树中,应该只存在指向具有关联内容的类别的路径。
我的结构是一个数组:
[uid_of_category]
=> (array)content
=> empty
=> (array)sub_categories
=> [uid_of_category]
=> (array)content
=> empty
=> (array)sub_categories
=> [uid_of_category]
=> (array)content
=> [...associated content...]
=> (array)sub_categories
[uid_of_category]
=> (array)content
=> empty
=> (array)sub_categories
=> [uid_of_category]
=> (array)content
=> [...associated content...]
=> (array)sub_categories
=> [uid_of_category]
=> (array)content
=> empty
=> (array)sub_categories
=> [uid_of_category]
=> (array)content
=> [...associated content...]
=> (array)sub_categories
...我尝试使用递归函数来获取树的最低层元素,但我不知道如何实现这些元素保留在树中,这些元素没有关联的内容,但其子元素有关联的内容。
发布于 2021-10-28 16:00:36
显然,递归会有所帮助。但是让我们使用两个函数而不是一个。我们将使用一个函数来确定一个类别是否满足要清理(删除)的条件。另一个执行清理的函数。在此函数中,参数将通过引用传递(&$categories)。所有这些都假设结构是一个数组。
cleanCategories($categories);
function cleanCategories(&$categories)
{
foreach ($categories as $key=>&$category) {
if (isCleanable($category)) {
unset($categories[$key]);
} else {
cleanCategories($category['sub_categories']);
}
}
}
function isCleanable($category)
{
if (!empty($category['content'])) {
return false;
}
foreach ($category['sub_categories'] as $category) {
if (!isCleanable($category)) {
return false;
}
}
return true;
}通过这种方法,您可以做一个更好、更有效的解决方案。
别忘了Stack Overflow不是一个写代码的服务。你必须自己思考,再思考,找到一种方法(只是思考),把它放到代码中,尝试代码,调试代码……
发布于 2021-10-28 09:29:37
尝试基于OP的帖子构建一个数组:
$arr = [
"uid_of_category_0" => [
"content" => [],
"sub_categories" => [
"uid_of_category_0_0" => [
"content" => [],
"sub_categories" => []
],
"uid_of_category_0_1" => [
"content" => [
"associated_content_0_1_0",
"associated_content_0_1_1",
"associated_content_0_1_2"
],
"sub_categories" => []
]
]
],
"uid_of_category_1" => [
"content" => [],
"sub_categories" => [
"uid_of_category_1_0" => [
"content" => [
"associated_content_1_0_0",
"associated_content_1_0_1",
"associated_content_1_0_2"
],
"sub_categories" => []
],
"uid_of_category_1_1" => [
"content" => [],
"sub_categories" => [
"uid_of_category_1_1_0" => [
"content" => [
"associated_content_1_1_0_0",
"associated_content_1_1_0_1",
"associated_content_1_1_0_2"
],
"sub_categories" => []
]
]
]
]
],
];下面是在$arr中取消设置所有空数组的代码:
function unset_empty_arrays(array $arr): array {
foreach (array_keys($arr) as $key) {
if (is_array($arr[$key])) {
$arr[$key] = unset_empty_arrays($arr[$key]);
}
if ($arr[$key] === [] && $key === 'sub_categories') {
unset($arr[$key]);
}
}
return $arr;
}
print_r(unset_empty_arrays($arr));编辑:添加了&& $key === 'sub_categories‘
发布于 2021-11-02 11:46:41
这种情况最好用树的后序遍历来解决。
在后序遍历中,您希望首先在所有子树上进行递归。然后在当前节点上执行所需的操作。
function cleanUp(&$categories) {
if (empty($categories)) {
//no categories, nothing to do here
return;
}
foreach ($categories as $key => &$category) {
//first clean up sub categories
cleanUp($category['sub_categories']);
if (empty($category['sub_categories']) && empty($category['content'])) {
//If there are no sub_categories left and there is no content remove category
unset($categories[$key]);
}
}
}对子类别进行清理后,您知道如果还有任何子类别,则它们必须有内容或带有内容的子类别。因此,在这一点上,您可以很容易地决定是否需要删除当前类别。
https://stackoverflow.com/questions/69705954
复制相似问题