扁平幼虫嵌套关系(后代父母)

时间:2019-07-15 12:21:29

标签: laravel laravel-5 eloquent

我的模型上有亲子关系。我想要的是弄平所有这些集合,包括所有父级的后代。

[
   {
      'name': 'Parent',
      'another_array' => [

          {
             'name': 'Another Array Name'
          }
      ],
      'children': [
         {
             'name': 'First Child',
             'address': 'lorem ipsum',
             'contact_no': '92390',


             'another_array' => [

                 {
                    'name': 'Another Array Name'
                 }
             ],
             'children': [
                {
                    'name': 'First Descendant',
                    'address': 'lorem ipsum',
                    'contact_no': '92390',
                    'children': [
                        {
                            'name': 'Descendant Child',
                            'address': 'lorem ipsum',
                            'contact_no': '92390',
                            'children': [
                                {
                                   'name': 'Last Descendant',
                                   'address': '',
                                   'contact_no': '',
                                   'children': []
                                }
                            ]

                        }
                    ]
                }
             ]
         }
      ]
   }
]


我尝试了以下代码。但是,它仅显示子级的第二深度。它不会显示该集合的下一个子代​​。

User.php
public function parent()
{
    return $this->belongsTo(User::class, 'id', 'parent_id');
}

public function children()
{

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

public function descendants()
{
    return $this->children()->with('descendants');
}

UsersController.php

public function index()
{
    $parent = User::find(1);

    $parent->with('descendants')->find($parent->id);

    $descendants = $this->traverseTree($parent->descendants);

    return response($descendants);
}

protected function traverseTree($subtree)
{
    $descendants = collect([]);

    foreach ($subtree->descendants as $descendant) {

       $descendants->push($descendant);

       if($descendant->descendants instanceof Collection) {

          foreach ($descendant->descendants as $node) {

             $this->traverseTree($node);

             $descendants->push($node);
          }
       }
   }

   return $descendants;
}

所需的输出


    [
        {
            'name': 'Parent',
            'address': 'lorem ipsum',
            'contact_no': '92390'
        },
        {
            'name': 'First Child',
            'address': 'lorem ipsum',
                 'contact_no': '92390'
        },
        {
            'name': 'First Descendant',
            'address': 'lorem ipsum',
                 'contact_no': '92390',
        },
        {
            'name': 'Descendant Child',
            'address': 'lorem ipsum',
                 'contact_no': '92390',
        },
        {
            'name': 'Last Descendant' ,
            'address': '',
                 'contact_no': '',
        }

    ]

期待您的帮助。

1 个答案:

答案 0 :(得分:1)

从集合响应中通过链接toArray()方法将其转换为数组,这样您就可以输出并变成一个多维数组,而不是嵌套对象,如下所示...

       $my_array = [
            'name' => 'Parent',
            'children' => [
                 'name' => 'First Child',
                 'address' => 'lorem ipsum',
                 'contact_no' => '234',
                 'children' => [
                    'name' => 'First Descendant',
                     'address' => 'lorem ipsum',
                     'contact_no' => '567',
                    'children' => [
                        'name' => 'Descendant Child',
                        'address' => 'lorem ipsum',
                        'contact_no' => '8890',
                        'children' => [
                            'name' => 'Last Descendant',
                            'address' => '',
                            'contact_no' => '',
                            'children' =>  []
                        ]
                    ]
                 ]
            ]
        ];

然后您可以在下面使用此帮助功能:

protected function _flattened($array)
    {
        $flatArray = [];

        if (!is_array($array)) {
            $array = (array)$array;
        }

        foreach($array as $key => $value) {
            if (is_array($value) || is_object($value)) {
                $flatArray = array_merge($flatArray, $this->_flattened($value));
            } else {
                $flatArray[0][$key] = $value;
            }
        }

        return $flatArray;
    }

在转储$result = $this->_flattened($my_array);时,您将得到类似...的输出

       [
            0 => [
                "name" => "Parent"
            ],
            1 => [
                "name" => "First Child",
                "address" => "lorem ipsum"
                "contact_no" => "234"
            ],
            2 => [
                "name" => "First Descendant"
                "address" => "lorem ipsum"
                "contact_no" => "567"
            ],
            3 => [
                "name" => "Descendant Child"
                "address" => "lorem ipsum"
                "contact_no" => "8890"
            ],
            4 => [
                "name" => "Last Descendant"
                "address" => ""
                "contact_no" => ""
            ],
        ];