【问题标题】:Flatten laravel nested relationship (parent to descendants)展平 laravel 嵌套关系(父到子)
【发布时间】:2019-07-15 12:21:29
【问题描述】:

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

[
   {
      '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': '',
        }

    ]

期待您的帮助。

【问题讨论】:

    标签: laravel laravel-5 eloquent


    【解决方案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" => ""
                ],
            ];
    

    【讨论】:

    • 你确定array_walk_recursive 吗?因为输出给了我错误的输出。
    • @Jearson 你的输出是什么样的?确保它是多维数组
    • 出于演示目的,我没有包含其他属性,如地址、联系人编号等。当我包含时,它也会添加到数组输出中。
    • @Jearson 我现在有一个解决方案,我会更新我之前发布的答案
    • 在这种情况下,您的答案适用于一个嵌套关系,适用于儿童。但是,如果我急切地加载另一个关系(例如 another_array),输出将附加 another_array。我更新了有关问题的数据。假设数组有另一个 another_array..
    猜你喜欢
    • 2020-08-20
    • 2014-10-27
    • 2015-02-26
    • 1970-01-01
    • 2021-01-20
    • 2018-06-07
    • 2021-07-19
    • 2019-06-18
    • 1970-01-01
    相关资源
    最近更新 更多