首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从类别树中清理空类别

从类别树中清理空类别
EN

Stack Overflow用户
提问于 2021-10-25 09:52:11
回答 4查看 192关注 0票数 2

我已经创建了一个类别树,其中每个类别都包含子类别,每个类别都包含其关联的内容。此树中的某些类别包含子类别,但没有关联的内容。如何清理类别树,以便树结构只包含具有关联内容的类别,或者具有具有关联内容的子类别的类别?也就是说,在类别树中,应该只存在指向具有关联内容的类别的路径。

我的结构是一个数组:

代码语言:javascript
复制
[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
               ...

我尝试使用递归函数来获取树的最低层元素,但我不知道如何实现这些元素保留在树中,这些元素没有关联的内容,但其子元素有关联的内容。

EN

回答 4

Stack Overflow用户

发布于 2021-10-28 16:00:36

显然,递归会有所帮助。但是让我们使用两个函数而不是一个。我们将使用一个函数来确定一个类别是否满足要清理(删除)的条件。另一个执行清理的函数。在此函数中,参数将通过引用传递(&$categories)。所有这些都假设结构是一个数组。

代码语言:javascript
复制
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不是一个写代码的服务。你必须自己思考,再思考,找到一种方法(只是思考),把它放到代码中,尝试代码,调试代码……

票数 3
EN

Stack Overflow用户

发布于 2021-10-28 09:29:37

尝试基于OP的帖子构建一个数组:

代码语言:javascript
复制
$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中取消设置所有空数组的代码:

代码语言:javascript
复制
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‘

票数 0
EN

Stack Overflow用户

发布于 2021-11-02 11:46:41

这种情况最好用树的后序遍历来解决。

在后序遍历中,您希望首先在所有子树上进行递归。然后在当前节点上执行所需的操作。

代码语言:javascript
复制
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]);
        }
    }
}

对子类别进行清理后,您知道如果还有任何子类别,则它们必须有内容或带有内容的子类别。因此,在这一点上,您可以很容易地决定是否需要删除当前类别。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69705954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档