Массив дерева 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'
]

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

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
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
)

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