Как отсортировать иерархически многомерный массив по уровням - PullRequest
1 голос
/ 12 апреля 2019

Мне нужно отсортировать массив иерархически по столбцу уровня.

Я извлекаю эти данные из заголовков HTML (h1, h2, h3 ...), и мне необходимо организовать их иерархически в виде массива.В основном это будет использоваться для отображения «Оглавления».

** Отредактировано **

// The soluction (Thanks @trincot)
static public function build_hierarchy( &$links, $level = 1 ) {

    $result = [];
    while (current($links)) {
        if ( current($links)["level"] > $level ) {
           $result[ count($result)-1 ]["children"] = static::build_hierarchy($links, $level+1);
        }
        if (current($links)["level"] < $level ) return $result; // backtrack
        $result[] = current($links);
        next($links);
    }
    return $result;
}

У меня есть следующий массив:

     Array(
            [0] =  Array( 
                    'level' => '1', 
                    'id' => 'item 1', 
                    'content' => 'item 1'
            ),
            [1] =  Array( 
                    'level' => '1', 
                    'id' => 'item 2', 
                    'content' => 'item 2'
            ),
            [2] =  Array( 
                    'level' => '2', 
                    'id' => 'item 3', 
                    'content' => 'item 3'
            ),
            [3] =  Array( 
                    'level' => '2', 
                    'id' => 'item 4', 
                    'content' => 'item 4'
            ),
            [4] =  Array( 
                    'level' => '2', 
                    'id' => 'item 5', 
                    'content' => 'item 5'
            ),
            [5] =  Array( 
                    'level' => '3', 
                    'id' => 'item 6', 
                    'content' => 'item 6'
            ),
            [6] =  Array( 
                    'level' => '1', 
                    'id' => 'item 7', 
                    'content' => 'item 7'
            ),  

        )

Iнужен вывод (по столбцу уровня):

Array(
    [0] =  Array( 
            'level' => '1', 
            'id' => 'item 1', 
            'content' => 'item 1'   
        ),
    [1] =  Array( 
            'level' => '1', 
            'id' => 'item 2', 
            'content' => 'item 2',
            'childrens' => Array(
                [0] = Array(
                    'level' => '2', 
                    'id' => 'item 3', 
                    'content' => 'item 3'
                ),
                [1] = Array(
                    'level' => '2', 
                    'id' => 'item 4', 
                    'content' => 'item 4'
                ),
                [2] = Array(
                    'level' => '2', 
                    'id' => 'item 5', 
                    'content' => 'item 5',
                    'childrens' => Array(
                        [0] = Array(
                            'level' => '3', 
                            'id' => 'item 6', 
                            'content' => 'item 6'
                        )
                    )
                ),
            )
        ),
    [2] =  Array( 
        'level' => '1', 
        'id' => 'item 7', 
        'content' => 'item 7'   
    )
)

Я не могу этого сделать!Мне нужна ваша помощь.

** Обновление 1: **

Я не могу течь с логикой этого!Я пытался в течение двух дней!Я не знаю, как, например, перейти с уровня 3 на уровень 1 , это кажется невозможным!

1 Ответ

0 голосов
/ 12 апреля 2019

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

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

Вот как бы я это написал:

function build_hierarchy(&$links, $level = 1) {
    $result = [];
    while (current($links)) {
        if (current($links)["level"] > $level ) {
            $result[max(0, count($result)-1)]["children"] = build_hierarchy($links, $level+1);
        }
        if (current($links)["level"] < $level ) return $result; // backtrack
        $result[] = current($links);
        next($links);
    }
    return $result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...