Поиск потомков подкатегории из подкатегории

В настоящее время у меня есть фрагмент кода, в котором для каждой категории он найдет подкатегории:

   $categories = array_map(
        function($child)
        {
            $child['children'] =
                $this->getChildren(
                    $child['id'],
                    !empty($this->request->get['language_id']) ?
                        $this->request->get['language_id'] : 1
                );
            return $child;
        }, $categories);

getChildren() рекурсивно получит потомков одной категории:

private function getChildren($parent_id, $language_id) {
    $this->load->model('official/category');

    $children = 
        $this->model_official_category->getCategoriesByParentId(
            $parent_id,
            $language_id
        );

    // For each child, find the children.
    foreach ($children as $child) {
        $child['children'] = $this->getChildren(
            $child['id'],
            $language_id
        );
    }

    return $children;
}

В настоящее время при использовании моей лямбда-функции в array_map() будут извлечены только дочерние элементы подкатегории, поэтому, если каждая подкатегория имеет свою собственную подкатегорию, она не будет сохранена в своих дочерних элементах.

Как я могу показать подкатегорию с учетом имеющейся подкатегории?

Что я хотел сделать со своим кодом, так это взять родителя, получить его дочерние элементы, а затем рассматривать каждого из этих дочерних элементов как родительский и рекурсивно получать его дочерние элементы, однако мой вывод JSON не отражает этого. Только у родителя есть дети - у детей нет детей (несмотря на то, что они есть в моей базе данных).


person theGreenCabbage    schedule 03.11.2014    source источник


Ответы (1)


Проблема в том, что ваш цикл рекурсии foreach назначает извлекаемых потомков копией дочерних данных, а не самим дочерним данным.

Чтобы решить эту проблему, вы можете использовать цикл foreach, который ссылается на дочерние данные, например:

foreach ($children as &$child) {

Однако по ряду причин, связанных с внутренней реализацией foreach в PHP (дополнительная информация, если вам интересно), было бы гораздо эффективнее использовать вместо этого цикл for, так как это позволит избежать множества копий при записи дочерние данные:

for ($i = 0; isset($children[$i]); $i++) {
    $children[$i]['children'] = $this->getChildren(
        $children[$i]['id'],
        $language_id
    );
}

Это то место, где использование объектов вместо массивов для представления дочерних данных может быть хорошей идеей, потому что объекты всегда передаются по ссылке (своего рода), и поведение будет больше похоже на то, что вы ожидали изначально.

person DaveRandom    schedule 03.11.2014
comment
Прекрасный ответ. Спасибо. Вы предлагаете использовать циклы for вместо foreach во всех ситуациях? Исходя из Java, циклы for автоматически кажутся мне более интуитивно понятными и удобочитаемыми. - person theGreenCabbage; 03.11.2014
comment
@theGreenCabbage во всех ситуациях, когда вы перебираете массив (не объект) и когда вы изменяете массив в цикле, да. - person DaveRandom; 03.11.2014