为了账号安全,请及时绑定邮箱和手机立即绑定

从嵌套数组中删除无子元素(叶子除外)

从嵌套数组中删除无子元素(叶子除外)

PHP
慕桂英3389331 2021-11-05 10:42:59
我有一个称为表mappings有id,leaf,parent_id,name和flip_parent列。parent_id和flip_parent都是引用 的整数mapping。id柱子。flip_parent持有一个应该从树中排除的值的 id。为此,我有以下函数($mappings都是mappings表中的所有行,flipParentIds都是同一个表中的flip_parent值不是null)private function removeFlipParents(array $mappings, array $flipParentIds){    foreach ($mappings as $key => $mapping) {        foreach ($flipParentIds as $id) {            if ($mapping['id'] === $id['flipParent']) {                unset($mappings[$key]);            }        }    }    return $mappings;}删除这些值后,我需要用剩余的数据构建一棵树(树有 5/6 层深),这是通过以下代码完成的;private function buildTree(array $elements, $parentId){    $branch = [];    foreach ($elements as $element) {       if ($element['parentId'] == $parentId) {            $children = $this->buildTree($elements, $element['id']);            if ($children) {                $element['children'] = $children;            } else {                $element['children'] = [];            }        }    }    return $branch;}在这种情况下elements与 相同的数组$mappings,但没有那些翻转父母。此函数的结果作为 JSON 响应返回,并由 Javascript 处理以构建树。返回的 JSON 结构与此类似;[{    "id": 1, "name": "Node 1", "children": [{      "id": 2, "name": "Node 1.1", "children": [{        "id": 4, "name": "Node 1.1.1", "leaf": true, "children": [], "gls": [{          "id": 1000, "name": "GL1", "code": "0100"        }, {          "id": 1001, "name": "GL2", "code": "0200"        }]      }, {        "id": 5, "name": "Node 1.1.2", "leaf": true, "children": [], "gls": [{          "id": 2000, "name": "GL3", "code": "0300"        }, {          "id": 2001, "name": "GL4", "code": "0400"        }]      }]    }, {      "id": 3, "name": "Node 1.2", "children": [{        "id": 6, "name": "Node 1.2.1", "leaf": true, "children": [], "gls": [{          "id": 3000, "name": "GL5", "code": "0500"        }, {          "id": 3001, "name": "GL6", "code": "0600"        }]      }]    }]  }, 
查看完整描述

1 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

您将在$node['children']此行中传递数组的副本$this->removeChildlessBranches($node['children']);(如果您在查找通过引用和通过值传递之前还没有听说过它)。因此,将对该副本进行任何后续更改,而不是对原始数组(也是副本)进行更改。更改的结果然后被丢弃,因为您没有对它们做任何事情。


您可以通过将行更改为 this 来解决该问题$nodes[$key]['children'] = $this->removeChildlessBranches($node['children']);。


但是请注意,您现在可能有一个没有子节点且不是叶节点的节点,但由于您已经在该级别进行了修剪,因此不会被正确删除。首先修剪孩子然后取消设置应该会给你想要的结果:


private function removeChildlessBranches(array $nodes)

{

    foreach ($nodes as $key => $node) {

        $nodes[$key]['children'] = $this->removeChildlessBranches($node['children']);


        if (empty($nodes[$key]['children']) && !$nodes[$key]['leaf']) {

            unset($nodes[$key]);

        }

    }


    return $nodes;

}


查看完整回答
反对 回复 2021-11-05
  • 1 回答
  • 0 关注
  • 121 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信