powered by simpleCommunicator - 2.0.18     © 2024 Programmizd 02
Map
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP - запутался со ссылками
4 сообщений из 4, страница 1 из 1
PHP - запутался со ссылками
    #40132569
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то не соображу, где ошибка.

Нужно сформировать из текста иерархическую структуру.
Иерархия строится по отступам (пробелам) в тексте.

Написал такой код:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
function tree_init($data)
{
	if (!isset($data)) return;
	if (!is_array($data)) $data = explode("\n", $data);
	$tree = null;
	$stack = null;
	foreach ($data as $line)
	{
		$lvl = strlen($line) - strlen(ltrim($line, ' '));
		$line = trim($line);
		if (!$line) continue;
		list($code,$name) = explode(' ', $line, 2);
		if (!$code) continue;
		if ($lvl == 0) {
			$stack = [];
			$tree = [];
			$ref = &$tree;
		} else {
			if ($lvl == count($stack)) {
				null;
			} elseif ($lvl < count($stack)) {
				while (count($stack) > $lvl) array_pop($stack);
				$ref = $stack[$lvl-1];
			} else {
				$stack[] = &$ref;
				$ref = &$ref['list'];
			}
		}
		$ref = ['code'=>$code, 'name'=>$name, 'cnt'=>0, 'list'=>[]];
	}
	return $tree;
}

$tree = <<<TEXT
root Перечень
 ??? Прочее
 tie 0.Узлы связи
  core 0.Опорные
  dist 1.Агрегация
  node 2.Доступ
  knot 3.Муфты
  clnt 4.Клиенты
 trc 1.Линии воздушные
  knot 0.Опоры
  bone 1.Магистрали
  leaf 2.Отводы
  pwrl 8.PoE
 lnk 2.Линии подземные
  knot 0.Колодцы
  bone 1.Магистрали
  leaf 2.Отводы
 obj 3.Объекты
  cmrc ТЦ
 cam 4.Камеры
  site 0.Камеры
  area 1.Зоны
 tag 8.Информация
  excl 0.Важное
  info 1.Подробности
  temp 9.Временное
 prj 9.Проекты
  site 0.Сооружения
  line 1.Линии
  temp 9.Временное
TEXT;
$tree = tree_init($tree);
print_r($tree);


Но результат получается неправильный, в полученной иерархии нет возврата назад.
Если записать так: $ref = &$stack[$lvl-1]
то результат тоже неправильный, предшествующая структура не сохраняется.
...
Рейтинг: 0 / 0
PHP - запутался со ссылками
    #40132587
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот так получается лучше.
Но почему-то остается только один дочерний узел.
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
function tree_init($data)
{
	if (!isset($data)) return;
	if (!is_array($data)) $data = explode("\n", $data);
	$tree = null;
	$stack = null;
	foreach ($data as $line)
	{
		$lvl = strlen($line) - strlen(ltrim($line, ' '));
		$line = trim($line);
		if (!$line) continue;
		list($code,$name) = explode(' ', $line, 2);
		if (!$code) continue;
		if ($lvl == 0) {
			$tree = ['_code'=>$code, '_name'=>$name, '_cnt'=>0];
			$stack = [];
			$ref = & $tree;
			continue;
		} else {
			if ($lvl == count($stack)) {
				null;
			} elseif ($lvl < count($stack)) {
				while (count($stack) > $lvl) array_pop($stack);
				if (!array_key_exists($code, $stack[$lvl-1]))$stack[$lvl-1][$code] = [];
				$ref = & $stack[$lvl-1][$code];
			} else {
				$stack[] = & $ref;
				if (!array_key_exists($code, $ref)) $ref[$code] = [];
				$ref = & $ref[$code];
			}
		}
		$ref['_code'] = $code;
		$ref['_name'] = $name;
		$ref['_cnt'] = 0;
	}
	return $tree;
}
...
Рейтинг: 0 / 0
PHP - запутался со ссылками
    #40132613
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделал так:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
function tree_init($data)
{
	if (!isset($data)) return;
	if (!is_array($data)) $data = explode("\n", $data);
	$tree = null;
	foreach ($data as $line)
	{
		$lvl = strlen($line) - strlen(ltrim($line, ' '));
		$line = trim($line);
		if (!$line) continue;
		list($code,$name) = explode(' ', $line, 2);
		if (!$code) continue;
		if ($lvl == 0) {
			unset($tree);
			$tree = [];
			$stack = [];
		} else {
			if ($lvl == count($stack)) {
				$tree = $stack[$lvl-1];
				if (!array_key_exists($code, $tree)) $tree[$code] = [];
				$tree = &$tree[$code];
			} elseif ($lvl < count($stack)) {
				while (count($stack) > $lvl+1) array_pop($stack);
				$tree = array_pop($stack);
				if (!array_key_exists($code, $tree)) $tree[$code] = [];
				$tree = &$tree[$code];
			} else {
				$stack[] = &$tree;
				if (!array_key_exists($code, $tree)) $tree[$code] = [];
				$tree = &$tree[$code];
			}
		}
print "$lvl $code "; foreach ($stack as $s) print ">{$s['_code']}"; print "\n";
		$tree['_code'] = $code;
		$tree['_name'] = $name;
		$tree['_cnt'] = 0;
	}
	return $tree;
}


В отладочном выводе содержимое стека правильное.
Но в результате почему-то только последнее значение.
...
Рейтинг: 0 / 0
PHP - запутался со ссылками
    #40132631
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот так работает правильно:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
function tree_init($data)
{
	if (!isset($data)) return;
	if (!is_array($data)) $data = explode("\n", $data);
	$tree = null;
	foreach ($data as $line)
	{
		$lvl = strlen($line) - strlen(ltrim($line, ' '));
		$line = trim($line);
		if (!$line) continue;
		list($code,$name) = explode(' ', $line, 2);
		if (!$code) continue;
		if ($lvl == 0) {
			unset($tree);
			$tree = [];
			$stack = [];
			$root = &$tree;
		} else {
			if ($lvl == count($stack)) {
				unset($ref); $ref = &$stack[$lvl-1];
				if (!array_key_exists($code, $ref)) $ref[$code] = [];
				unset($tree); $tree = &$ref[$code];
			} elseif ($lvl < count($stack)) {
				unset($ref); $ref = &$stack[$lvl-1];
				while (count($stack) > $lvl) array_pop($stack);
				if (!array_key_exists($code, $ref)) $ref[$code] = [];
				unset($tree); $tree = &$ref[$code];
			} else {
				$stack[] = &$tree;
				unset($ref); $ref = &$tree;
				if (!array_key_exists($code, $ref)) $ref[$code] = [];
				unset($tree); $tree = &$ref[$code];
			}
		}
		$tree['_code'] = $code;
		$tree['_name'] = $name;
		$tree['_cnt'] = 0;
	}
	return $root;
}



Но хотелось бы без обходных маневров с unset и вспомогательной переменной.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PHP - запутался со ссылками
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (1): Анонимы (1)
Читали форум (1): Анонимы (1)
Пользователи онлайн (9): Анонимы (6), Bing Bot, Yandex Bot, RePredeclared 4 мин.
x
x
Закрыть


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