Laravel объединяется во вложенный массив с данными из другого массива на основе идентификатора ключа - PullRequest
0 голосов
/ 06 декабря 2018

Стараемся решить эту проблему с помощью коллекций Laravel или помощников массивов наиболее эффективным способом.Кто-нибудь может помочь с этим?

$menu = [
    ["id"=>1],
    ["id"=>2],
    ["id"=>3,"children"=>[
        ["id"=>4]
    ]],
    ["id"=>5,"children"=>[
        ["id"=>6],
        ["id"=>7,"children"=>[
            ["id"=>8],
            ["id"=>9]
        ]]
    ]],
    ["id"=>10]
];

$pages = [
    ['id'=>1,'label'=>'About Us','url_path'=>'/about-us'],
    ['id'=>2,'label'=>'Meet the Team','url_path'=>'/meet-the-team'],
    ['id'=>3,'label'=>'Services','url_path'=>'/services'],
    ['id'=>4,'label'=>'Contact Us','url_path'=>'/contact-us'],
    ['id'=>5,'label'=>'Company Mission','url_path'=>'/company-mission'],
    ['id'=>6,'label'=>'History','url_path'=>'/history'],
    ...
    ...
];

Ключ ID из вложенного массива $ menu должен выполнить поиск в массиве $ pages на основе того же идентификатора, а затем объединить всю строку обратно в $ menu.

Моя функция:

$menu = collect($menu)->map(function($item) use($pages){
    $page_item = collect($pages)->firstWhere('id',$item['id']);
    if(array_has($item,'children')){
        $page_item['children'] = ...
    }
    return $page_item;
})->toArray();

Как добавить данные массива из $ pages в «children» с рекурсивной итерацией?И есть ли лучший способ сделать эту функцию более эффективной?Я хочу использовать коллекции Laravel или помощники массивов для решения этой проблемы вместо использования цикла foreach и т. Д.

Ниже приведен ожидаемый результат:

$menu = [
    ["id"=>1,"label"=>"About Us","url_path"=>"/about-us"],
    ["id"=>2,"label"=>"Meet the Team","url_path"=>"/meet-the-team"],
    ["id"=>3,"label"=>"Services","url_path"=>"/services","children"=>[
        ["id"=>4,"label"=>"Contact Us","url_path"=>"/contact-us"]
    ]],
    ["id"=>5,"label"=>"Company Mission","url_path"=>"/company-mission","children"=>[
        ["id"=>6,"label"=>"History","url_path"=>"/history"],
        ["id"=>7, ...
    ...
];

Может кто-нибудь показать мне?Спасибо!

1 Ответ

0 голосов
/ 06 декабря 2018

Этого можно добиться с помощью рекурсивной функции:

function map_pages_to_menu(array $pages, array $menu) {
    return collect($menu)->map(function ($menu_item) use ($pages){

        // find the page item that matches menu id
        $page_item = collect($pages)->firstWhere('id',$menu_item['id']);

        // if there is a match create the menu item from the page item
        $menu_item = $page_item ? array_merge($menu_item, $page_item) : [];

        // if there are children inside menu item, recursively find matching page items.
        if(array_has($menu_item,'children')){
            $menu_item['children'] = map_pages_to_menu($pages, $menu_item['children']);
        }

        return $menu_item;
    })
    // to remove empty items & reset index
    ->filter()->values()
    ->toArray();
}

$menu = '[
    {"id":1},
    {"id":2},
    {"id":3,"children":[
        {"id":4}
    ]},
    {"id":5,"children":[
        {"id":6},
        {"id":7,"children":[
            {"id":8},
            {"id":9}
        ]}
    ]},
    {"id":10}
]';

$menu = json_decode($menu, true);

$pages = [
    ['id'=>1,'label'=>'About Us','url_path'=>'/about-us'],
    ['id'=>2,'label'=>'Meet the Team','url_path'=>'/meet-the-team'],
    ['id'=>3,'label'=>'Services','url_path'=>'/services'],
    ['id'=>4,'label'=>'Contact Us','url_path'=>'/contact-us'],
    ['id'=>5,'label'=>'Company Mission','url_path'=>'/company-mission'],
    ['id'=>6,'label'=>'History','url_path'=>'/history']
];

$menu = map_pages_to_menu($pages, $menu);

echo json_encode($menu);

Фрагмент: https://implode.io/yTmrDO

...