Получить массив выбранных элементов и его дочерние элементы

У меня есть php-массив массивов, возвращаемый внешней системой в следующем формате

$elements = [
    [
        'id' => 1,
        'name' => 'Element 1',
        'parent_id' => 0
    ],
    [
        'id' => 2,
        'name' => 'Element 2',
        'parent_id' => 0
    ],
    [
        'id' => 3,
        'name' => 'Element 3',
        'parent_id' => 1
    ],
    [
        'id' => 4,
        'name' => 'Element 4',
        'parent_id' => 1
    ],
    [
        'id' => 5,
        'name' => 'Element 5',
        'parent_id' => 1
    ],
    [
        'id' => 6,
        'name' => 'Element 6',
        'parent_id' => 2
    ],
    [
        'id' => 7,
        'name' => 'Element 7',
        'parent_id' => 2
    ],
    [
        'id' => 8,
        'name' => 'Element 8',
        'parent_id' => 3
    ],
    [
        'id' => 9,
        'name' => 'Element 9',
        'parent_id' => 3
    ],
    [
        'id' => 10,
        'name' => 'Element 10',
        'parent_id' => 3
    ]
];

Если это поможет, эта структура, «переведенная» на дерево, будет выглядеть так:

  • Элемент 1
    • Элемент 3
      • Элемент 8
      • Элемент 9
      • Элемент 10
    • Элемент 4
    • Элемент 5
  • Элемент 2
    • Элемент 6
    • Элемент 7

Теперь мне нужно сделать следующее: для данного списка идентификаторов вернуть все элементы с предоставленными идентификаторами и их дочерними элементами (независимо от того, сколько уровней). Например, если я получаю массив с [2, 3], вывод должен быть [2, 3, 7, 8, 9, 10].

Я создал функцию для создания древовидной структуры на основе массива:

    public function createTree($parent = 0)
    {
        // This returns all the direct children of $parent
        $elements = filterByParent($parent); 
        $categories = [];
        $i = 0;
        foreach ($elements as $element) {
            $categories[$i] = $element;
            $categories[$i]['children'] = createTree($element['id']);
            $i++;
        }

        return $categories;
    }

Но я не знаю, как теперь поступить.

Любая помощь будет оценена по достоинству.

Заранее спасибо!

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
30
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я изменил методы, так как довольно легко создать список из одного рекурсивного метода. Это также передается в $elements, чтобы его можно было легко протестировать.

Метод может принимать либо идентификатор, либо массив идентификаторов, если это один идентификатор, то он делает его массивом, чтобы он мог foreach() по списку. Затем он просто проверяет его на соответствие каждому элементу и добавляет в рабочий список. Затем вызывает тот же метод, чтобы найти дополнительные подэлементы.

function dependants ( $ids, $elements )  {
    if ( !is_array($ids) )   {
        $ids = [$ids];
    }
    $deps = $ids;
    foreach ( $ids as $id ) {
        foreach ( $elements as $element )   {
            if ( $element['parent_id'] == $id ) {
                $deps = array_merge($deps, dependants($element['id'], $elements));
            }
        }
    }
    return $deps;
}
print_r(dependants([2,3], $elements ));

дает

Array
(
    [0] => 2
    [1] => 3
    [2] => 6
    [3] => 7
    [4] => 8
    [5] => 9
    [6] => 10
)

Это потрясающе, большое спасибо! Я попытался добавить оператор if, чтобы также включить 2 и 3 в список результатов (предоставленные параметры), но он дублирует элементы. Есть ли способ включить их? Если нет, я думаю, я могу просто получить иждивенцев и array_merge с параметрами

TJ is too short 07.02.2019 21:22

Я переместил место добавления идентификатора, чтобы он добавлялся в начале, а не в середине.

Nigel Ren 07.02.2019 21:42

Большое спасибо! Я слишком усложнял проблему. Это выглядит так просто и так элегантно по сравнению с моим кодом.

TJ is too short 07.02.2019 22:23

Другие вопросы по теме