Массив дерева PHP Flatten, сопоставление с ключом нового формата массива => значение

У меня есть сложный массив в php, например:

[
    0 => [
        'id' => '2'
        'parent_id' => '1'
        'text' => 'Algoritma'
        'lvl' => '1'
        'nodes' => [
            0 => [
                'id' => '11'
                'parent_id' => '2'
                'text' => 'Flowchart'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=11'
            ]
            1 => [
                'id' => '12'
                'parent_id' => '2'
                'text' => 'Pseudo code'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=12'
            ]
        ]
        'href' => '/site/read-by-type?id=2'
    ]
    1 => [
        'id' => '3'
        'parent_id' => '1'
        'text' => 'Pemrograman'
        'lvl' => '1'
        'nodes' => [
            0 => [
                'id' => '4'
                'parent_id' => '3'
                'text' => 'Java'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=4'
            ]
            1 => [
                'id' => '5'
                'parent_id' => '3'
                'text' => 'PHP'
                'lvl' => '2'
                'nodes' => [
                    0 => [
                        'id' => '8'
                        'parent_id' => '5'
                        'text' => 'Yii2 Framework'
                        'lvl' => '3'
                        'href' => '/site/read-by-type?id=8'
                    ]
                    1 => [
                        'id' => '9'
                        'parent_id' => '5'
                        'text' => 'Laravel'
                        'lvl' => '3'
                        'href' => '/site/read-by-type?id=9'
                    ]
                ]
                'href' => '/site/read-by-type?id=5'
            ]
            2 => [
                'id' => '7'
                'parent_id' => '3'
                'text' => 'Javascript'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=7'
            ]
        ]
        'href' => '/site/read-by-type?id=3'
    ]
    2 => [
        'id' => '10'
        'parent_id' => '1'
        'text' => 'Sistem Operasi'
        'lvl' => '1'
        'nodes' => [
            0 => [
                'id' => '13'
                'parent_id' => '10'
                'text' => 'Mac OS'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=13'
            ]
            1 => [
                'id' => '14'
                'parent_id' => '10'
                'text' => 'Linux'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=14'
            ]
        ]
        'href' => '/site/read-by-type?id=10'
    ]
]

Мне нужно преобразовать этот массив в формат значения ключа в ['id' => 'text']:

[
    2  => ' Algoritma'           // with 1 spaces based on those level
    11 => '  Flowchart',         // with 2 spaces based on those level
    12 => '  Pseudo code',       // with 2 spaces based on those level
    3  => ' Pemrograman'         // with 1 spaces based on those level
    4  => '  Java'               // with 2 spaces based on those level
    5  => '  PHP'                // with 2 spaces based on those level
    8  => '   Yii2 Framework'    // with 3 spaces based on those level
    9  => '   Laravel'           // with 3 spaces based on those level
    10 => ' Sistem Operasi'      // with 1 spaces based on those level

    ... so on
]

Пока что я пишу такой код:

public static function flattingTree(array $tree){
    $denormalizeTree = [];
    foreach ($tree as $node) {

        if (isset($node['nodes'])){
           // I am stuck  ...
        }

        $denormalizeTree[$node['id']] = $node['text'];
    }

    return $denormalizeTree;
}

И я только что получил только один уровень:

[
    2 => 'Algoritma'
    3 => 'Pemrograman'
    10 => 'Sistem Operasi'
]

Любая помощь, которую он так ценит...

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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 и хотите разрабатывать...
1
0
23
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Быстрым решением будет использование рекурсивной функции, которая перебирает массивы и добавляет нужные данные в окончательный массив.

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

function extract($arr, &$saveInto) {
    foreach ($arr as $el) {
        isset($el['id'], $el['text']) && ($saveInto[$el['id']] = $el['text']);
        isset($el['nodes']) && extract($el['nodes'], $saveInto); // recursive call
    }
}

Используя приведенную выше функцию, вы можете сгладить свой массив, вызвав его и указав переменную, которая будет содержать результат.

$unflattenedArr = [ ... ]; // the array to be flattened
$finalArr = []; // the array that will hold the result
extract($unflattenedArr, $finalArr);
// at this stage $finalArr holds the result you need.

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

function flatten($arr) {
    $r = []; // this function prepares an empty variable
    extract($arr, $r); // passes it to "extract" function
    return $r; // then returns it with the desired result
}

Теперь вы можете сгладить свой массив следующим образом:

$unflattenedArr = [ ... ]; // the array to be flattened
$finalArr = flatten($unflattenedArr); // call the new function that encapsulates "extract" function
// at this stage $finalArr holds the result you need.

Надеюсь, я подтолкнул вас дальше.

Вы ближе, чем вы думаете. Просто вызовите свою функцию рекурсивно и добавьте результат в свой окончательный массив.

public function flattingTree(array $tree)
{
    $denormalizeTree = [];
    foreach ($tree as $node) {
        if (isset($node['nodes'])) {
            $denormalizeTree += $this->flattingTree($node['nodes']);
        }
        $denormalizeTree[$node['id']] = $node['text'];
    }

    return $denormalizeTree;
}

Результат:

$result = $this->flattingTree($array); 
print_r($result);

Array
(
    [11] => Flowchart
    [12] => Pseudo code
    [2] => Algoritma
    [4] => Java
    [8] => Yii2 Framework
    [9] => Laravel
    [5] => PHP
    [7] => Javascript
    [3] => Pemrograman
    [13] => Mac OS
    [14] => Linux
    [10] => Sistem Operasi
)

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