Dynami c вложенный объект в PHP Laravel - PullRequest
0 голосов
/ 23 февраля 2020

Я пытаюсь вложить свой объект в зависимости от значения parent. Я хочу вложить массив в его родительский. Вот мой пример объекта:

    $mainObject = [
        {
            id : 1,
            title : 'title 1',
            parent: 0,
        },
        {
            id : 2,
            title : 'title 2',
            parent: 0
        },
        {
            id : 3,
            title : 'title 3',
            parent: 1
        },
        {
            id : 4,
            title : 'title 4',
            parent: 1
        },
        {
            id : 5,
            title : 'title 5',
            parent: 4
        },
        {
            id : 6,
            title : 'title 6',
            parent: 4
        }
    ];

Теперь я хочу создать что-то вроде этого ниже

    $mainObject = [
        {
            id : 1,
            title : 'title 1',
            parent: 0,
            children: [
                {
                    id : 3,
                    title : 'title 3',
                    parent: 1
                },
                {
                    id : 4,
                    title : 'title 4',
                    parent: 1,
                    children: [
                        {
                            id : 5,
                            title : 'title 5',
                            parent: 4
                        },
                        {
                            id : 6,
                            title : 'title 6',
                            parent: 4
                        }
                    ]
                },
            ]
        },
        {
            id : 2,
            title : 'title 2',
            parent: 0
        },
    ];

Мой foreach

            $nested = [];

            foreach ($mainObject as $v) {
                if($v->parent == 0){
                    array_push($nested, $v);
                }
            }

Я пытался foreach и сгруппировать их, но я не мог понять, как я могу добиться 3-уровневого гнезда, как указано выше. Пожалуйста, помогите мне, я был на складе в течение 2 ночей.

Обратите внимание, что $mainObject является ответом от моего laravel app. Вы можете поделиться JS решением или vue.

Ответы [ 2 ]

0 голосов
/ 24 февраля 2020

Придумал решение, которое использует Laravel Коллекции и не использует рекурсию:

$array1 = [
        (object)[
            'id' => 1,
            'title' => 'title 1',
            'parent' => 0,
        ],
        (object)[
            'id' => 2,
            'title' => 'title 2',
            'parent' => 0
        ],
        (object)[
            'id' => 3,
            'title' => 'title 3',
            'parent' => 1
        ],
        (object)[
            'id' => 4,
            'title' => 'title 4',
            'parent' => 1
        ],
        (object)[
            'id' => 5,
            'title' => 'title 5',
            'parent' => 4
        ],
        (object)[
            'id' => 6,
            'title' => 'title 6',
            'parent' => 4
        ]
];

//PHP < 7.4
function nestArrayByParent($array){
    $collection = Illuminate\Support\Collection::wrap($array);

    //for each array element, by reference
    foreach($collection as &$obj){
        if(!property_exists($obj, 'parent') || $obj->parent == 0) //parent is 0 or doesn't have parent att.
            continue; //ignore.
        $parentKey = $collection->search(function($item) use($obj){
            return $item->id == $obj->parent;
        });
        $parent =& $collection[$parentKey]; //parent to which we must add $obj (by reference)

        if(!property_exists($parent, 'children') || !$parent->children)
            $parent->children = collect([]); //initialize children att if doesn't have it
        $parent->children->push($obj); //add $obj to its parent.
    }

    return $collection->filter(function($obj){
        //keep only items from the top level.
        return !property_exists($obj, 'parent') || $obj->parent == 0; 
    });
}

//PHP >= 7.4, with arrow functions
function nestArrayByParent_7_4($array){
    $collection = Illuminate\Support\Collection::wrap($array);

    //for each array element, by reference
    foreach($collection as &$obj){
        if(!property_exists($obj, 'parent') || $obj->parent == 0) //parent is 0 or doesn't have parent att.
            continue; //ignore.
        $parentKey = $collection->search(fn($item) => $item->id == $obj->parent);
        $parent =& $collection[$parentKey]; //parent to which we must add $obj (by reference)

        if(!property_exists($parent, 'children') || !$parent->children)
            $parent->children = collect([]); //initialize children att if doesn't have it
        $parent->children->push($obj); //add $obj to its parent.
    }

    //keep only items from the top level.
    return $collection->filter(fn($obj) => !property_exists($obj, 'parent') || $obj->parent == 0); 
}

//

dd(nestArrayByParent($array1));
0 голосов
/ 23 февраля 2020

Потратив 3-4 часа, я решил использовать массив. Проверьте решение в версии массива следующим образом:

$mainObject = '[
    {
        "id" : "1",
        "title" : "title 1",
        "parent": "0"
    },
    {
        "id" : "2",
        "title" : "title 2",
        "parent": "0"
    },
    {
        "id" : "3",
        "title" : "title 3",
        "parent": "1"
    },
    {
        "id" : "4",
        "title" : "title 4",
        "parent": "1"
    },
    {
        "id" : "5",
        "title" : "title 5",
        "parent": "4"
    },
    {
        "id" : "6",
        "title" : "title 6",
        "parent": "4"
    }
]';

$mainArray = json_decode($mainObject, true);

function recurse_uls ($array, $parent)
{
    $return = array();
    foreach ($array as $c => $p)  {
        if ($p['parent'] != $parent) continue;
        $return[] = $p;
        $data = recurse_uls ($array, $p['id']);
        if($data) {
            $length = count($return);
            $return[$length - 1]['children'] = $data;
        }
    }
    return empty($return) ? null : $return;
}

$data = recurse_uls ($mainArray, 0);
echo "<pre>"; 
print_r($data);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...