Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Как рекурсивно обойти многоуровневую глобаль / 11 сообщений из 11, страница 1 из 1
19.06.2011, 10:07
    #37314536
DarkKnight
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
Добрый день, подскажите пожалуйста, как можно рекурсивно (а именно с помощью рекурсивной функции) обойти все уровни многоуровневой глобали, заранее благодарен
...
Рейтинг: 0 / 0
19.06.2011, 10:27
    #37314547
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
$order - по одному уровню, для каждого уровня нужно писать свой цикл
Либо то же без циклов, но с рекурсивным вызовом, тогда еще нужны операторы косвенности @,@@, и обратный оператор $name.

$query - сплошной проход глобала сквозь все уровни,
тут нужно будет использовать операторы косвенности, и $qlength,$qsusbcript для определения, на каком же уровне глобала мы находимся и прочитывания данных.
...
Рейтинг: 0 / 0
19.06.2011, 11:16
    #37314571
DarkKnight
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
Спасибо за ответ.
А можно ли небольшой примерчик по 2ому предложеному вами варианту
Блок А.Н.Либо то же без циклов, но с рекурсивным вызовом, тогда еще нужны операторы косвенности @,@@, и обратный оператор $name.
...
Рейтинг: 0 / 0
19.06.2011, 11:37
    #37314580
DarkKnight
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
Лучшее что я смог придумать это две функции, причем выглядят они ужастно, чего только стоит _"""""
Может то что пытаюсь работать с глобалью так как работал бы с динамич. конструкцией на том же cpp, тоесть неверен сам подход.

Код: plaintext
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.
ClassMethod GenerateMenu()
{
	
	k ^Menu
	s ^Menu(1) = "Главное меню"	
		s ^Menu(1,1) = "Функционал группы A"
			s ^Menu(1,1,1) = "Func1"
			s ^Menu(1,1,2) = "Func2"			
		s ^Menu(1,2) = "Функция2"			
		s ^Menu(1,3) = "Выход"
	s ^Menu(2) = "Справка"
	s ^Menu(2,1) = "-"
	s ^Menu(2,2) = "О Программе"
		
	w "Генерация успешно произведена",!
}

//Тут обходим первый уровень глобали (назовем их главные узлы)
ClassMethod RootNode()
{
	s key = $o(^Menu(""),1,desc)
	while (key '= "")
	{
		w desc,!
		//Ну а в этом месте уже пошла сама рекурсия
		d ..GetMenu(key)
		s key = $o(^Menu(key),1,desc)	
	}
}
//Тут как раз да самая рекурсивная функция
ClassMethod GetMenu(Index As %String) As %String
{
	s gl = "^Menu("_Index_","_""""")"
	s key = $o(@gl,1,desc)
	
	while (key '= "")
	{
		w desc,!	
		s gl = "^Menu("_Index_","_key_")"
		d ..GetMenu(Index_","_key)
		s key = $o(@gl,1,desc)
	}
}
...
Рейтинг: 0 / 0
19.06.2011, 12:22
    #37314596
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
используя $q

Код: plaintext
1.
2.
3.
4.
5.
6.
 s key="^Menu("""")"
 for{s key=$q(@key) q:key=""
 	 w !,key
 	 w " =>",$qs(key, 0 ),"("
 	 f i= 1 : 1 :$ql(key) w $select(i= 1 :"", 1 :","),$qs(key,i)
 	 w ")=",@key 	 
 	}
...
Рейтинг: 0 / 0
19.06.2011, 12:31
    #37314600
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
используя рекурсивный вызов и $o
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 //d menu^menu("^Menu")
menu(gbl,level= 0 )
 n i,key
 s key=""
 for{s key=$o(@gbl@(key)) q:key=""
 	 f i= 0 : 1 :level w "  "
 	 w key,"=>",$g(@gbl@(key)),!
 	 d menu^menu($name(@gbl@(key)),level+ 1 )
 	}
...
Рейтинг: 0 / 0
19.06.2011, 13:35
    #37314643
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
Я как всегда, плохо прочитал ваше сообщение, но ничего, нужны вам вариант там тоже есть.

Другой вопрос, что сама структура хранения странная, если вам нужно показать "вот как я умею", она пойдет.
А если делать реальную разработку, то я бы порекомендовал классические реляционные таблицы, каждый пункт меню отдельной записью, ссылки типа uplink и т.д.
...
Рейтинг: 0 / 0
19.06.2011, 16:27
    #37314774
DarkKnight
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
Блок А.Н.,

Вы не совсем правы, есть Клиент(C++ связь с Cache идет по ActiveX), есть Server(Cache ).
Требуется описывать отображение функционала - в Cache(на Сервере), обработку функционала на Клиенте(C++ приложение).
В данном случае если расмотреть обычное меню, то структура на Cache будет примерно такова:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Class POPULATOR.Menu Extends %Persistent
{

//Текстовое отображения элемента меню
Property Caption As %String;

//Имя функционала
Property NameFunction As %String;

//Список дочерних элементов меню для данного элемента меню
Property Items As list Of Menu;

//Указатель на Parent элемент
Property Parent As POPULATOR.Menu;

//Индекс
Property Id As %Integer;
}
Далее клиент по ActiveX получит данные и сгенерирует меню, для клиента суть месаджа будет являться поле NameFunction, которое однозначно будет указывать о функциональности данного действия. Неопреденый процесс на клиенте, но описанный на сервере, будет в свою очередь служить предпосылкой в реализации этого метода на клиенте(или в сокопупности клиет-сервер реализации).
По-мне так все логично.

А по поводу:
"Другой вопрос, что сама структура хранения странная, если вам нужно показать "вот как я умею", она пойдет."
Я честно признаюсь, на данный момент - для меня Каш'е, как лес дремучий, и толком - я ничего не умею, но к этому нужно стремиться ;-)
...
Рейтинг: 0 / 0
19.06.2011, 17:12
    #37314819
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
Честно говоря, я не совсем понял, в чем я неправ, т.е. какое из моих высказываний вы оспариваете :-)

Еще непонятно, кто вы, студент, которому нужно сдать и забыть, или разработчик.
Я предполагаю второе, если я ошибся, то дальнейший текст не имеет смысла.

По поводу разработки на каше, это объектно-реляционная СУБД, и я предпочитаю данные хранить реляционным способом (в классах-таблицах), а программироваться на SQL и объектах. Это самый простой способ создания приложений, и наиболее гибкий в плане доработки.
Чистые глобалы использовать вижу смысл в определенных специфических случаях, например, когда нужно сделать что-то совершенно особенное.
Также многомерные переменные я использую в пределах программы, но избегаю использовать для постоянного хранения.
Если же нужно все-таки особенное хранение данных, то я стараюсь его настроить через настройку хранения класса.

Поправил ваш класс
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Class POPULATOR.Menu Extends %Persistent
{

/// Текстовое отображения элемента меню
Property Caption As %String;

/// Имя функционала
Property NameFunction As %String;

Index ParentIndex On Parent;

Relationship Parent As POPULATOR.Menu [ Cardinality = one, Inverse = Items ];

Relationship Items As POPULATOR.Menu [ Cardinality = many, Inverse = Parent ];

}
...
Рейтинг: 0 / 0
20.06.2011, 18:08
    #37316433
doublefint
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
Два способа хранения иерархических данных в реляционной СУБД
http://dev.mysql.com/tech-resources/articles/hierarchical-data.html
http://www.sitepoint.com/article/hierarchical-data-database
Имея под рукой глобали, обсуждать, как хранить иерархические данные... ;)
...
Рейтинг: 0 / 0
20.06.2011, 18:47
    #37316554
doublefint
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как рекурсивно обойти многоуровневую глобаль
DarkKnight, конкретно по вашему коду, можно избавится от метода RootNode, сделав упор на то, что рекурсивная функция выводит группу узлов:

Код: plaintext
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.
Class Test.Recursive Extends %CSP.Page {

Parameter CHARSET = "utf-8";

/// Инициализация 
ClassMethod Init() As %Status {
  k ^Menu
  s ^Menu( 1 ) = "Главное меню" 
  s ^( 1 , 1 ) = "Функционал группы A" ;^Menu( 1 , 1 )
  s ^( 1 , 1 ) = "Func1" ;^Menu( 1 , 1 , 1 )
  s ^( 2 ) = "Func2" ;^Menu( 1 , 1 , 2 )
  s ^Menu( 1 , 2 ) = "Функция2"   
  s ^( 3 ) = "Выход"   ;^Menu( 1 , 3 )
  s ^Menu( 2 ) = "Справка"
  s ^( 2 , 1 ) = "-"       ;^Menu( 2 , 1 )
  s ^( 2 ) = "О Программе"  ;^Menu( 2 , 2 )
 Q $$$OK
}

/// Выводим узлы!!!, не узел 
ClassMethod wNodes(gln As %String) As %Status {
  Q:$g(gln)="" $$$OK  
  Q:$d(@gln)< 10  $$$OK
  w "<ul>"
  s id=""  for { s id=$o(@gln@(id)) Q:id=""
   w !,"<li>",$g(@gln@(id))
   if $d(@gln@(id))> 1  {
    s subgln=$na(@gln@(id)) 
    d ..wNodes(subgln)
   }
   w "</li>"
  }
  w "</ul>"
}

///Отображение на веб-странице
ClassMethod OnPage() As %Status [ ServerOnly =  1  ] {
 &html<<html><head>
 <meta http-equiv="Content-Language" content="ru">
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>Рекурсивный проход</title></head><body>>
 d ..Init() ;заполнение глобали
 d ..wNodes("^Menu") ;собственно, запуск
 &html<</body></html>>
 Quit $$$OK
}

}
...
Рейтинг: 0 / 0
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Как рекурсивно обойти многоуровневую глобаль / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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