Эффективный способ построить дерево и отфильтровать категории без файлов - PullRequest
0 голосов
/ 07 мая 2020

У меня есть MySQL запрос $categories = dibi::query('SELECT * FROM [download] ')->fetchAssoc('download_id'), который возвращает массив элементов из БД, массив выглядит как

Array
(
    [3] => Dibi\Row Object
(
    [download_id] => 3
            [title] => Certifikáty jakosti
[id_parent] => 0
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:1:{i:1;a:2:{s:5:"nazev";s:29:"cert-qms-tttttttt-2017-en.pdf";s:5:"title";s:29:"cert-qms-tttttttt-2017-en.pdf";}}
            [last_edit] => Dibi\DateTime Object
(
    [date] => 2020-05-07 16:51:32.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Belgrade
                )

            [id_users] => 1
        )

    [4] => Dibi\Row Object
(
    [download_id] => 4
            [title] => Okna a dveře
[id_parent] => 0
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:0:{}
            [last_edit] => 
            [id_users] => 1
        )

    [5] => Dibi\Row Object
(
    [download_id] => 5
            [title] => CE štítky
[id_parent] => 0
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:0:{}
            [last_edit] => 
            [id_users] => 1
        )

    [6] => Dibi\Row Object
(
    [download_id] => 6
            [title] => Profilové systémy
[id_parent] => 0
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:0:{}
            [last_edit] => 
            [id_users] => 1
        )

    [7] => Dibi\Row Object
(
    [download_id] => 7
            [title] => Potrubní systémy
[id_parent] => 0
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:0:{}
            [last_edit] => 
            [id_users] => 1
        )

    [8] => Dibi\Row Object
(
    [download_id] => 8
            [title] => GDPR
[id_parent] => 0
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:0:{}
            [last_edit] => 
            [id_users] => 1
        )

    [9] => Dibi\Row Object
(
    [download_id] => 9
            [title] => ISO
[id_parent] => 3
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:3:{i:3;a:2:{s:5:"nazev";s:31:"cert-qms-tttttttt-2017-cz_1.pdf";s:5:"title";s:26:"Certifikát ISO 9001 (NQA)";}i:2;a:2:{s:5:"nazev";s:31:"cert-qms-tttttttt-2017-ru_1.pdf";s:5:"title";s:34:"Certifikát ISO 9001 (NQA) - rusky";}i:1;a:2:{s:5:"nazev";s:31:"cert-qms-tttttttt-2017-en_1.pdf";s:5:"title";s:37:"Certifikát ISO 9001 (NQA) - anglicky";}}
            [last_edit] => Dibi\DateTime Object
(
    [date] => 2020-05-07 10:03:24.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Belgrade
                )

            [id_users] => 1
        )

    [10] => Dibi\Row Object
(
    [download_id] => 10
            [title] => Prospekty a informace
[id_parent] => 4
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:1:{i:1;a:2:{s:5:"nazev";s:29:"cert-qms-tttttttt-2017-cz.pdf";s:5:"title";s:29:"cert-qms-tttttttt-2017-cz.pdf";}}
            [last_edit] => Dibi\DateTime Object
(
    [date] => 2020-05-07 15:44:19.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Belgrade
                )

            [id_users] => 1
        )

    [11] => Dibi\Row Object
(
    [download_id] => 11
            [title] => Výkresy
[id_parent] => 4
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:0:{}
            [last_edit] => 
            [id_users] => 1
        )

    [12] => Dibi\Row Object
(
    [download_id] => 12
            [title] => Certifikáty na vlastnosti
[id_parent] => 4
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:0:{}
            [last_edit] => 
            [id_users] => 1
        )

    [13] => Dibi\Row Object
(
    [download_id] => 13
            [title] => Návody
[id_parent] => 4
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:0:{}
            [last_edit] => 
            [id_users] => 1
        )

    [14] => Dibi\Row Object
(
    [download_id] => 14
            [title] => test
[id_parent] => 9
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:0:{}
            [last_edit] => 
            [id_users] => 1
        )

    [15] => Dibi\Row Object
(
    [download_id] => 15
            [title] => aaaaaaaaaaaaaaaah
[id_parent] => 14
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:1:{i:1;a:2:{s:5:"nazev";s:29:"cert-qms-tttttttt-2017-en.pdf";s:5:"title";s:29:"cert-qms-tttttttt-2017-en.pdf";}}
            [last_edit] => Dibi\DateTime Object
(
    [date] => 2020-05-07 15:47:40.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Belgrade
                )

            [id_users] => 1
        )

    [16] => Dibi\Row Object
(
    [download_id] => 16
            [title] => test
[id_parent] => 6
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:1:{i:1;a:2:{s:5:"nazev";s:29:"cert-qms-tttttttt-2017-en.pdf";s:5:"title";s:29:"cert-qms-tttttttt-2017-en.pdf";}}
            [last_edit] => Dibi\DateTime Object
(
    [date] => 2020-05-07 16:47:20.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Belgrade
                )

            [id_users] => 1
        )

    [17] => Dibi\Row Object
(
    [download_id] => 17
            [title] => test 2
            [id_parent] => 16
            [sort] => 0
            [active] => 1
            [lng] => 
            [files] => a:1:{i:1;a:2:{s:5:"nazev";s:29:"cert-qms-tttttttt-2017-en.pdf";s:5:"title";s:29:"cert-qms-tttttttt-2017-en.pdf";}}
            [last_edit] => Dibi\DateTime Object
(
    [date] => 2020-05-07 16:24:23.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Belgrade
                )

            [id_users] => 1
        )

)

Затем я обрабатываю файлы и делаю кучу других вещей, мой вопрос вот как я должен подойти к созданию дерева.

Мой первоначальный подход заключался в построении дерева из элементов в массиве. Функция выглядит так:

    private function getCategoryTree($categories = [], $id_parent = 0) {
        $tree = [];
        foreach ($categories as $category) {
            if ($category->id_parent == $id_parent) {
                $tree[$category->download_id] = $category;
                $subCategory = $this->getCategoryTree($categories, $category->download_id);
                if ($subCategory) {
                    $tree[$category->download_id]['category'] = $subCategory;
                }
            }
        }
        return $tree;
    }
 )


Какой бы элемент ни имел id_parent = 0, это категория верхнего уровня. Любая категория может иметь бесконечное количество подкатегорий, которые затем могут иметь бесконечное количество подкатегорий, и et c.

Мне в основном приходилось рекурсивно пройти через весь массив и сначала удалить самый «внутренний» объект Dibi \ Row, у которого не было файлов. Затем мне пришлось избавиться от всех пустых категорий, и я потерпел неудачу. Я не мог придумать, как это сделать.

Теперь я выбрал слишком сложный подход, когда

  1. я сначала использую плоский массив и отфильтровываю все объекты Dibi \ Row, у которых нет файлов
  2. Я нахожу все идентификаторы объектов Dibi \ Row, которые мне нужны
  3. Сделайте еще один запрос к БД $categories = dibi::query('SELECT * FROM [download] WHERE [download_id] IN (%i)', $ids)->fetchAssoc('download_id');, где $ ids - это массив, содержащий все идентификаторы Dibi \ Row Objecs, и на основе этого я создаю бренд новое дерево.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...