Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Эмиралька Эксперт
Вступление в Клуб: 09.11.2015
|
Вт Апр 05, 2022 05:41  цикл foreach |
|
Полезность: Нет оценки
|
-del-
Последний раз редактировалось: Эмиралька (Вт Апр 05, 2022 05:57), всего редактировалось 1 раз |
|
 |
Эмиралька Эксперт
Вступление в Клуб: 09.11.2015
|
Вт Апр 05, 2022 05:52  Re: цикл foreach |
|
Полезность: 4
|
Эмиралька пишет: | В библиотеке RUNTIME.LIB_MACRO есть замечательный макрос foreach.
его смысл в том, чтобы выполнить обход массива данных.
обычно для этого пишется цикл while, в котором обязательно должен быть индекс, который нужно объявить в начале процедуры. При этом нужно помнить, как индексирован массив, чтобы объявить правильный индекс. В цикле foreach индекс объявляется как параметр макроса без указания типа. Тип определится сам:
Код: |
iIdx integer;
begin
iIdx := aArray.first;
while iIdx is not null loop
| vs Код: |
&foreach(aArray, iIdx)
|
При этом в цикле while обязательно нужно предусматривать сдвиги итератора. Если забудете - можно получить бесконечный цикл. В цикле foreach сдвиг выполняется автоматически:
Код: |
iIdx integer;
begin
iIdx := aArray.first;
while iIdx is not null loop
if условие then
iIdx := aArray.next(iIdx);
continue;
end if;
iIdx := aArray.next(iIdx);
end loop;
| vs Код: |
&foreach(aArray, iIdx)
if условие then
continue;
end if;
-- или даже ещё проще
&continue_when(условие);
&end_foreach;
|
Чтобы прочитать элемент массива в переменную, при использовании стандартных подходов, требуется знать её тип, и, опять же, выполнить это в начале процедуры. При объёме процедуры в сотню строк это очень неудобно. При наличии двух-трёх циклов уже непонятно где какая переменная. В цикле foreach тип знать не нужно, объявление происходит так же в виде параметра:
Код: |
iIdx integer;
recTest rec_test;
begin
iIdx := aArray.first;
while iIdx is not null loop
recTest := aArray(iIdx);
if условие then
iIdx := aArray.next(iIdx);
continue;
end if;
iIdx := aArray.next(iIdx);
end loop;
| vs Код: |
begin
&foreach(recTest in aArray, iIdx)
if условие then
continue;
end if;
&end_foreach;
|
Чтобы поменять направление обхода, в цикле while нужно заменить first на last, next на prior, причём в куче мест и не ошибиться - во вложенных циклах этого делать не нужно.
Для foreach достаточно одного ключевого слова:
Код: |
iIdx integer;
recTest rec_test;
iTmp integer;
begin
iIdx := aArray.last;
while iIdx is not null loop
recTest := aArray(iIdx);
if условие then
iIdx := aArray.prior(iIdx);
continue;
end if;
iTmp := aArray.next(iIdx);
while iTmp is not null loop
iTmp := aArray.next(iTmp);
debug_pipe(aArray(iTmp).vNum, 0);
end loop;
iIdx := aArray.prior(iIdx);
end loop;
| vs Код: |
begin
&foreach(recTest in reverse aArray, iIdx)
if условие then
continue;
end if;
&foreach(aArray, iTmp := aArray.next(iIdx))
debug_pipe(aArray(iTmp).vNum, 0);
&end_foreach;
&end_foreach;
|
Если индексация массива внезапно изменилась и массив стал индексироваться по строке, для цикла while придётся как минимум сменить тип переменной-индекса. Для цикла foreach делать не нужно ничего!
Если начать обход массива нужно не с начала, а с определённой позиции, в цикле foreach это делается элементарно:
Код: |
iIdx varchar2;
recTest rec_test;
begin
iIdx := aArray.prior('20202');
while iIdx is not null loop
recTest := aArray(iIdx);
if условие then
iIdx := aArray.prior(iIdx);
continue;
end if;
iIdx := aArray.prior(iIdx);
end loop;
| vs Код: |
begin
&foreach(recTest in reverse aArray, iIdx := aArray.prior('20202'))
if условие then
continue;
end if;
&end_foreach;
|
Параметр-индекс необязателен:
Код: |
begin
&foreach(recTest in aArray)
continue_when(условие);
&end_foreach;
|
за счёт того, что внутри макроса используется begin-end, все переменные, объявленные внутри цикла, переинициализируются на каждой итерации. Область видимости этих переменных - тоже ограничена циклом.
Код: |
begin
&foreach(recTest in aArray)
continue_when(условие);
var vNum varchar2;
vNum := recTest.vNum;
&end_foreach;
|
Вот такой интересный макрос. |
|
|
 |
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|