RPGLE I-серии выполняет поиск общих значений в нескольких массивах

#arrays #ibm-midrange #rpgle

#массивы #ibm-midrange #rpgle

Вопрос:

Я пытаюсь выяснить, как искать общие значения в нескольких вхождениях массива с помощью RPGLE, и пока безуспешно. Что я пытаюсь сделать, так это выяснить, сколько массивов используют одни и те же общие значения. Каждый массив имеет длину 1, а длина массива достигает 100. Например:

 Array 1 = 'a' 'b' 'c' 'd' 'e' 'f' ' ' ' '.....
Array 2 = 'a' 'b' 'c' 'd' 'e' 'g' ' ' ' '.....
Array 3 = 'd' 'c' 'a' 'b' 'h' 'e' ' ' ' '.....
Array 4 = 'k' 'b' 'e' 'd' 'a' 'g' ' ' ' '.....
 

Я пытаюсь найти простой способ определить, являются ли буквы a, b, d и e общими для массивов, или каждая из этих букв является общей для массивов.

Есть ли у кого-нибудь идеи, как легко выполнить этот поиск, чтобы мне не приходилось попадать во вложенные do и if в ад? Это становится довольно сложным, когда заполняются все 100 элементов массива. Однако хорошей новостью является то, что существует только 10 массивов, которые можно заполнить.

Заранее спасибо!

Комментарии:

1. Ну, на самом деле это одноразовая программа очистки. У меня есть много тысяч значений записей, и мне нужно выяснить, какие записи содержат общие символы, и пометить их для удаления. я все больше и больше привыкаю к мысли, что мне, возможно, придется выполнять вложенные IF. Я собираюсь поспать сегодня вечером и посмотреть, произойдет ли чудо к утру, прежде чем я займусь этим. 🙂

2. Как обычно, я слишком много думал о проблеме, а не о решении. Эти записи сгруппированы, каждая группа разделена пробелом. Мне пришло в голову, что я мог бы поместить первую запись в массив и проверить следующие записи из группы для каждого символа из первой группы. Итак, если «a» была в первой группе, но не было записей ни из одной из других записей в группе, произошел сбой. Итак, всего несколько%-ных запросов при циклическом просмотре первой группы. Я уверен, что это ясно, как грязь, но я нашел выход. 🙂 Я планирую исследовать исходную проблему, о которой я спрашивал. 🙂

Ответ №1:

Что ж, хорошей новостью является то, что если вы используете 7.3 или 7.4, IBM только что выпустила некоторые улучшения RPG, включая FOR-EACH код операции и %LIST() bif

Плохие новости, я не думаю, что это будет волшебная палочка…

Вы ищете только значения, которые являются общими для всех 10 массивов?

В RPG нет INTERSECTION оператора … но в SQL есть.

Я бы подумал о создании 10 строк, разделенных запятыми
‘a, b, c, d, e, f, …’ для передачи в БД. Затем используйте функцию SPLIT() SQL (также в 7.3 и 7.4), чтобы разделить каждую строку на набор записей, для которых вы могли бы запросить ПЕРЕСЕЧЕНИЕ.

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

Решение, основанное только на RPG, представляет собой интересную задачу …

Ответ №2:

вот процедура, которая имеет немного общее назначение. Для сопоставления с этим массивом требуется массив из 256 строк с переменными символами и массив шаблонов. Возвращает ‘1’ или ‘1’ в зависимости от того, все ли элементы шаблона существуют во входном массиве.

 ** ------------------------ arr_containsAllArr -------------------
** check that inArr contains all the items in inPatternArr.
parr_containsAllArr...
p                 b
darr_containsAllArr...
d                 pi             1a
d inArr                        256a   const varying dim(100)
d inPatternArr                 256a   const varying dim(100)

d ix              s             10i 0
d fx              s             10i 0
d mx              s             10i 0
d doesContain     s              1a
d patternItem     s            256a   varying
 /free
      doesContain = '1' ;

  // for each patternArr item
      for         ix = 1 to 100 ;
      patternItem = inPatternArr(ix) ;
      if          %len(patternItem) > 0 ;
      fx          = %lookup( patternItem: inArr ) ;
      if          fx = 0 ;
      doesContain = '0' ;
      leave ;
      endif ;
      endif ;
      endfor ;

      return      doesContain ;
 /end-free
p                 e
 

код показывает, как используется процедура:

 d arr             s            256a   varying dim(100)
d patternArr      s            256a   varying dim(100)
d doesContain     s              1a
 /free
      clear       arr ;
      clear       patternArr ;
      arr(1)      = 'z' ;
      arr(2)      = 'a' ;
      arr(3)      = 'w' ;
      arr(4)      = 'm' ;
      patternArr(1)  = 'w' ;
      patternArr(2)  = 'd' ;
      patternArr(3)  = 'z' ;
      doesContain = arr_containsAllArr( arr: patternArr ) ;
      if          doesContain = '1' ;
      sendInfoMsg( 'does contain all items': 1 ) ;
      else ;
      sendInfoMsg( 'does not contain all items': 1 ) ;
      endif ;

  // contains 'm', 'z' and 'a'
      clear       patternArr ;
      patternArr(1)  = 'm' ;
      patternArr(2)  = 'a' ;
      patternArr(3)  = 'z' ;
      doesContain = arr_containsAllArr( arr: patternArr ) ;
      if          doesContain = '1' ;
      sendInfoMsg( 'does contain all items': 1 ) ;
      else ;
      sendInfoMsg( 'does not contain all items': 1 ) ;
      endif ;
 /end-free
 
 ** ----------------------- pr_Qmhsndpm -------------------------------
dpr_Qmhsndpm      pr                  extpgm('QMHSNDPM')
d InMsgid                        7a   const
d InMsgf                        20a   const
d InMsgData                  32767a   const options(*VarSize)
d InMsgDatal                    10i 0 const
d InMsgType                     10a   const
d InCsEntry                    256a   const options(*VarSize)
d InCsCounter                   10i 0 const
d OutMsgKey                      4a
d OutError                            likeds(zApiError )
d InCsEntryLx                   10i 0 const options(*NoPass)
d InCsQual                      20a   const options(*NoPass)
d InWaitTime                    10i 0 const options(*NoPass)

** ---------------------- zApiError ----------------------------
** zApiError - the ERRC0100 struct filled by system api calls.
dzApiError        ds                  qualified
d size                          10i 0 inz(%size(zApiError))
d BytesNeeded                   10i 0
d ExcpId                         7a
d Rsv1                           1a
d ExcpData                    2048a
 
 ** ---------------------- sendInfoMsg ---------------------------
psendInfoMsg...
p                 b                   export
dsendInfoMsg...
d                 pi
D InText                      2000    const varying
D InCallStackCx                 10i 0 Value options(*nopass)

d err             ds                  likeds(zApiError)
D Msgf            S             20a
d msgid           s              7a
d msgData         s           2000a
d msgDataLx       s             10i 0
D msgkey          S              4a
d MsgText         s           2000a
d msgType         s             20a
d callStackCx     s             10i 0
 /free
      Msgf        = 'QCPFMSG   *LIBL' ;
      msgid       = 'CPF9898' ;
      msgdata     = inText ;
      msgdataLx   = %len(%trimr(msgdata)) ;
      msgType     = '*INFO' ;
      callStackCx = 2 ;
      if          %parms >= 2 ;
      callStackCx  = inCallStackCx ;
      endif ;
      msgkey      = ' ' ;
      err.size    = %size(err) ;
      err.BytesNeeded = 0 ;
      pr_qmhsndpm( msgId: msgf: msgData: msgDataLx: msgType:
                   '*': callStackCx: MsgKey: err ) ;

 /end-free
p                 e
 

Комментарии:

1. Они, это довольно круто! Это не удовлетворяет всем требованиям, которые я выдвигаю, но я определенно вижу, что я мог бы изменить это, чтобы заставить его работать. Спасибо!

2. массивы очень ограничены в RPG. Я вроде как помню, что поиск ожидал сортировки массива. Но, похоже, в этом случае это работает. Просто нужно иметь в виду.

3. Да, расскажи мне об этом. Я проделал несколько довольно аккуратных действий с массивами в RPG, но этот был в значительной степени чрезмерным…. Мне пришлось изменить его для своих нужд, но приведенный выше код работает просто отлично!