Страница 1 из 2

Перечисляемые последовательности

Добавлено: 31 Январь 2021, 17:04
Игорь Столяров
Привет всем !

Хочу спросить, только не кидайте меня сразу в терновый куст ... :)
Постоянно сталкиваюсь с тем, что в коде нужно повторять действие для некого конечного числового ряда.
Например, что то вроде:

Код: Выделить всё

  Loop Column# = 1,4,6,7,1,5 ... и т.д.
     SetMyField(Column#)  ! Какое-то действие по номеру колонки
  end
Понятно, что выход есть всегда и мастерская костылей работает без выходных.
Но неужели нет простого решения для простой задачи ? :( Заранее спасибо ! :)

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 2:03
Admin
Что не нравится в текущем коде? Он простой и понятный.
Имеется в виду перебор очереди с какими то значениями.

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 2:04
Admin
Можно все в класс оформить с VIRTUAL и т.д. но это из пушки по воробьям кажется...

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 5:28
Игорь Столяров
Admin писал(а): 01 Февраль 2021, 2:03 Имеется в виду перебор очереди с какими то значениями
В том-то и дело, что нужно сначала что-то подготовить, а потом по этому перебрать.
Плюс некая структура данных, можно вот ещё и класс прикрутить ...
А просто, перебрать несколько чисел (1,4,6,7,1,5 и т.д.) в заданной последовательности нельзя ? :(

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 8:52
Ал
INLIST... (может использоваться до 25-ти элементов списка, но должно быть по крайней мере два)?
CHOOSE... ?

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 9:22
Игорь Столяров
Неа ... :( Теплее всего - это редко используемые сейчас структуры Itemize.
Но счастья не хватает возможности их динамического определения в процессе выполнения ... ;)

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 9:44
Ал
Игорь Столяров писал(а): 01 Февраль 2021, 9:22 Неа ... :( Теплее всего - это редко используемые сейчас структуры Itemize.
Но счастья не хватает возможности их динамического определения в процессе выполнения ... ;)
тут дело вкуса и подхода, а Itemize - это больше про константы...

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 9:49
RaFaeL
А для интереса, зачем нужен такой код? Ни разу не видел раньше

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 10:01
Ал
Clarion Databases & SQL, David Harms, Editor
Screen-2021-02-01_09-58-49.png

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 11:31
kreator
А банальные массивы не подойдут?

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 11:48
Игорь Столяров
kreator писал(а): 01 Февраль 2021, 11:31 А банальные массивы не подойдут?
А можно ли массив инициализировать одной командой ?

Перечисляемые последовательности

Добавлено: 01 Февраль 2021, 13:23
RaFaeL
Если код один и тот же, а меняются только цифры, то код можно вынести в процедуру, куда передавать строку, в которой закодированы цифры (001004006007001005)
Далее

Код: Выделить всё

loop i#=1 to len(Str) by 3
  SetMyField(str[i# : i#+2])
end

Перечисляемые последовательности

Добавлено: 02 Февраль 2021, 2:43
Admin
Могу предложить такой вариант...

Код: Выделить всё

  PROGRAM
  MAP
  END                       
  
IteratorQueue     QUEUE,TYPE
Item                &CSTRING
                  END

Iterator          CLASS,TYPE
Items               &IteratorQueue,PRIVATE
Position            LONG,PRIVATE
Construct           PROCEDURE
Destruct            PROCEDURE
Init                PROCEDURE(*QUEUE Q, LONG FieldPosition=1)
Init                PROCEDURE(STRING Items)
AddItem             PROCEDURE(STRING Item)
Count               PROCEDURE(),LONG   
Get                 PROCEDURE(),STRING  
Next                PROCEDURE(),STRING  
Kill                PROCEDURE 
                  END
  
IterOne           Iterator

TestQueue         QUEUE
ID                  LONG  
Number              LONG
                  END
  
  CODE            
  ! вариант 1
  IterOne.Init('1,2,3')
  LOOP IterOne.Count() TIMES
    MESSAGE(IterOne.Get())
  END
  IterOne.Kill           
  
  ! вариант 2
  IterOne.AddItem(100)
  IterOne.AddItem(200)
  IterOne.AddItem(300)
  LOOP IterOne.Count() TIMES
    MESSAGE(IterOne.Get())
  END
  IterOne.Kill           

  ! вариант 3
  LOOP W# = 1 TO 5
     TestQueue.ID = W#
     TestQueue.Number = RANDOM(1,1000)
     ADD(TestQueue)
  END
  IterOne.Init(TestQueue, 2)
  LOOP IterOne.Count() TIMES
    MESSAGE(IterOne.Get())
  END


Iterator.Construct           PROCEDURE
  CODE                            
  SELF.Items &= NEW IteratorQueue
  
Iterator.Destruct            PROCEDURE
  CODE           
  SELF.Kill
  DISPOSE(SELF.Items)

Iterator.Init                PROCEDURE(*QUEUE Q, LONG FieldPosition=1)
Cnt                          LONG
Field                        ANY   
  CODE
  LOOP Cnt = 1 TO RECORDS(Q)
    GET(Q, Cnt)
    Field &= WHAT(Q, FieldPosition)
    SELF.AddItem(Field)
  END

Iterator.Init                PROCEDURE(STRING Items)
SplitStrPos                  LONG,AUTO
StartPos                     LONG(1)      
Delimiter                    EQUATE(',')
  CODE                                                       
  LOOP
    SplitStrPos = INSTRING(Delimiter, Items, 1, StartPos)
    IF SplitStrPos
      SELF.AddItem(Items[StartPos : SplitStrPos-1])
      StartPos = SplitStrPos + LEN(Delimiter)
      IF StartPos > LEN(Items)
        BREAK
      END
    ELSE
      SELF.AddItem(Items[StartPos : LEN(Items)])
      BREAK
    END
  END

Iterator.AddItem             PROCEDURE(STRING Item)
  CODE                     
  SELF.Items.Item &= NEW CSTRING(LEN(Item)+1)
  SELF.Items.Item = CLIP(LEFT(Item))
  ADD(SELF.Items)

Iterator.Count               PROCEDURE()!,LONG
  CODE                                        
  RETURN RECORDS(SELF.Items)
  
Iterator.Get                 PROCEDURE()!,STRING  
  CODE
  RETURN SELF.Next()

Iterator.Next                PROCEDURE()!,STRING  
  CODE                       
  SELF.Position += 1
  GET(SELF.Items, SELF.Position)
  IF ERRORCODE() THEN RETURN '' END
  RETURN SELF.Items.Item

Iterator.Kill                PROCEDURE 
Cnt                          LONG
  CODE
  LOOP Cnt = 1 TO SELF.Count()
    GET(SELF.Items, Cnt)
    DISPOSE(SELF.Items.Item)
  END                
  FREE(SELF.Items)
  SELF.Position = 0

Перечисляемые последовательности

Добавлено: 02 Февраль 2021, 5:35
Игорь Столяров
Большое спасибо ! :)

1. Очень обрадовало, подобные вопросы возникали не только у меня. :)
2. Вариант 1 - это просто мечта. Буду его внедрять. :)

Перечисляемые последовательности

Добавлено: 02 Февраль 2021, 9:19
Admin
Игорь Столяров писал(а): 02 Февраль 2021, 5:35 1. Очень обрадовало, подобные вопросы возникали не только у меня. :)
Я просто взял и написал, сегодня :)