雄辩的递归关系

我有一个问题,我试图获取一个对象的所有后代并只保留那些具有特定属性的后代。


我有这些关系:


    public function getChildren()

    {

        return $this->hasMany(self::class, 'parent_id', 'id');

    }


    public function allChildren()

    {

        return $this->getChildren()->with('allChildren');

    }

例如,我得到这种类型的数组:


$array = [

           0 => ['name' => 'aaa', 'type' => 0, 'parent' => null, 'children' => [

                 1 => ['name' => 'bbb', 'type' => 1, 'parent' => null, 'children' => []], 

                 2 => ['name' => 'ccc', 'type' => 0, 'parent' => null, 'children' => [

                       3 => ['name' => 'ddd', 'type' => 1, 'parent' => 2, 'children' => []]

                        ]]

                    ]],

           4 => ['name' => 'eee', 'type' => 0, 'parent' => null, 'children' => []]

];

对于此示例,我想删除所有属于的对象type 1并获得一个干净的数组,而没有这些对象。


我真的不明白为什么可以获得一个对象的所有后代但不能通过条件。


提前致谢。


jeck猫
浏览 106回答 2
2回答

慕侠2389804

仅收集解决方案将是这样的(将自定义宏放在应用程序的服务提供者中):Collection::macro('whereDeep', function ($column, $operator, $value, $nested) {    return $this->where($column, $operator, $value)->map(function ($x) use ($column, $operator, $value, $nested) {        return $x->put($nested, $x->get($nested)->whereDeep($column, $operator, $value, $nested));    });});然后在需要的地方调用:$yourArray->whereDeep('type', '!=', 1, 'children');在您的示例中,宏的工作方式如下:过滤所有元素,其中:(type != 1外部数组将保持不变,因为两个项目都有type => 0)对于当前数组的每个元素:从本指令的第一点开始,检索该children属性并对该子数组应用相同的过滤。children用刚刚过滤的新子属性替换该属性。无论如何,您应该尝试深入研究为什么关系过滤不起作用。如果正确优化,该解决方案将更有效。

临摹微笑

我找到了一个很好的解决方案,不需要所有这些递归或任何这些关系调用,所以我分享它:使用:“gazsp/baum”// get your object with roots method$contents = Content::roots()->get();// and simply run through the object and get whatever you need // thanks to getDescendantsAndSelf method$myArray = [];foreach($contents as $content) { $myArray[] = $content->getDescendantsAndSelf()->where('type', '!=', 1)->toHierarchy();}return $myArray;这对我来说与上面的其他方法相同。
打开App,查看更多内容
随时随地看视频慕课网APP