powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Perl: обход иерархии без рекурсии
6 сообщений из 6, страница 1 из 1
Perl: обход иерархии без рекурсии
    #39680553
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сервер возвращает такую иерархическую json-структуру:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
{
    "Id":"d9f0cce7-3ff7-48b7-aa86-fd63ae312a6c",
    "Name":null,
    "ParentId":"00000000-0000-0000-0000-000000000000"
    "ChildObjects":[
    {
        "Id":"bb804b66-b5c2-460d-bdc5-9e2ab23e3ef2",
        "Name":"Группа 1",
        "ParentId":"d9f0cce7-3ff7-48b7-aa86-fd63ae312a6c"
        "ChildObjects":[ ... ],
    },
    {
        "Id":"b8ca2667-d242-4d23-9297-e62429b0ec60",
        "Name":"Группа 2",
        "ParentId":"d9f0cce7-3ff7-48b7-aa86-fd63ae312a6c"
        "ChildObjects":[ ... ],
    }
    ],
}


Иерархия строится через вложения ChildObjects, глубина неограничена.
Мне нужно из этой иерархии построить хеш такого вида:
Код: php
1.
2.
3.
4.
5.
$tree = {
"d9f0cce7-3ff7-48b7-aa86-fd63ae312a6c"=>"/",
"bb804b66-b5c2-460d-bdc5-9e2ab23e3ef2"=>"/Группа 1/",
"c9f74625-0193-4792-9735-9a25093ab248"=>"/Группа 1/Подгруппа 2/"
}


Через рекурсивный вызов функции я это сделал, примерно так:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
sub _tree($$)
{
	my $tree = shift;
	my $leaf = shift;
	my $base = (shift||'') . ($leaf->{'Name'}||'') . '\\';
	$tree->{$leaf->{'Id'}} = $base;
	&_tree($tree, $_, $base) foreach (@{$leaf->{'ChildObjects'}});
}
&_tree($tree, $json);



А можно ли обойтись без рекурсии?
...
Рейтинг: 0 / 0
Perl: обход иерархии без рекурсии
    #39681358
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.А можно ли обойтись без рекурсии?Да. Любую рекурсию можно переписать на цикл. Любой цикл можно повторить рекурсией.
Конкретно эту рекурсию мне переводить лень.
...
Рейтинг: 0 / 0
Perl: обход иерархии без рекурсии
    #39681385
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
всё можно, только структуру выбрать надо правильную
гуглите nodes tree

Деревья в базах данных можно хранить четырьмя основными методами: Adjacency List, Path Enumeration, Nested Set & Closure Table ( Нормальная Форма 1-2-3 ).
Если кратко, то:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
AL — когда у нас родитель хранится в колонке типа parent_id: '1'
PE — полный путь до элемента хранится в колонке типа path: '1.2.5' (? не годится, когда ПОДката может быть в нескольких НАДкатах ?). Хорош для "хлебных крошек" и сортировке по иерархии.
NS — пара колонок lft и rgt, хранящие диапазон всех вложенных элементов, например, корень дерева из 9 элементов будет иметь левое значение '1', а правое — '18'
    -- это дичь, когда при insert/delete нужно пересчитать ВСЁ дерево и ВСЕМ узлам по новой раздать parent_id/child_ids.
CT - Closure Table (обычная нормализация, причём с FK):  http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back/78-Antipattern_Categories_Database_Design_Database  (с 48 слайда)
    -- она типа должна требовать O(N**2) строк в НФ, но на практике гораздо меньше.
    -- в НФ надо добавить колонку `depth`, чтобы ещё быстрее родителя найти. А можно попробовать подключить массивы и пихать туда родичей. Чтобы не строчки плодить, а массив.
NS походу НЕ ГОДИТСЯ, когда кат-я может находиться в нескольких НАДкат-ях, потому что ID дублируется, а у NS кол-во right_key = кол-во_ID *2
они также не годятся и для комментариев/тикетов, потому что там в любых точках происходит коммент и всё остальное дерево надо пересчитывать. Если клиентов много, это будет 3.14здец.

вот тут 250 слайдов про кривые ручки, а с 48 про деревья (SQL Antipattern Strike Back)
(оттуда):
Код: plaintext
1.
2.
3.
4.
5.
Design                  № of Tables     Query child     Query subtree   Modify tree     Referential integrity
Adjacency List          1               Easy            Hard            Easy            +
Path Enumeration        1               Easy            Easy            Hard            -
Nested Sets             1               Hard            Easy            Hard            -
Closure Table           2               Easy            Easy            Easy            +

-- тут ещё описание скорости: https://demiurg.livejournal.com/53125.html?mode=reply
...
Рейтинг: 0 / 0
Perl: обход иерархии без рекурсии
    #39681399
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlКонкретно эту рекурсию мне переводить лень.
Я был бы признателен и за подсказку.
Но я сейчас понял, что я неправильно сформулировал вопрос.
Судя по упоминанию циклов, имелся ввиду проход в цикле с самодельными стеками.
Например добавляем в массив (стек) элементы первого уровня, обрабатываем их, затем добавляем в массив их потомков и повторяем, пока элементы не кончатся.

Если переформулировать вопрос, то я хотел спросить — есть ли в Perl встроенные механизмы или хитрости, чтобы развернуть иерархическую структуру в плоскую? Без самодельных стеков.
...
Рейтинг: 0 / 0
Perl: обход иерархии без рекурсии
    #39681474
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудухNS походу НЕ ГОДИТСЯ
NS как раз мог бы подойти — потому что я не формирую иерархию, а загружаю ее извне.
Но извне мне приходит уже готовая иерархия AL, поэтому нет практического смысла преобразовывать AL в NS, чтобы затем развернуть ее в плоский список. Тогда уж лучше сразу AL развернуть в список.
...
Рейтинг: 0 / 0
Perl: обход иерархии без рекурсии
    #39681522
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.Если переформулировать вопрос, то я хотел спросить — есть ли в Perl встроенные механизмы или хитрости, чтобы развернуть иерархическую структуру в плоскую? Без самодельных стеков.
у перла есть CPAN, там всё уже написано, тем более на такую тему, как деревья
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Perl: обход иерархии без рекурсии
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]