%SUBARR (配列の部分の設定/入手)

%SUBARR(array:start-index{:number-of-elements})

組み込み関数 %SUBARR は、指定された配列の、開始指標 から始まるセクションを戻します。 戻される要素の数は、オプションの要素の数 パラメーターで指定します。 このパラメーターを指定しない場合、要素の数 のデフォルト値として、 配列のそれ以降の部分の要素の数が使用されます。

%SUBARR の最初のパラメーターは配列でなければなりません。 つまり、配列として定義された独立のフィールド、データ構造、またはサブフィールドを指定する必要があります。 この最初のパラメーターは、テーブル名またはプロシージャー呼び出しであってはなりません。

開始指標 パラメーターは、小数点以下の桁数がゼロである 数値でなければなりません。 浮動小数点数値は使用できません。 この値は、1 以上で、かつ配列の要素数以下でなければなりません。

オプションの要素の数 パラメーターは、小数点以下の桁数がゼロである 数値でなければなりません。 浮動小数点数値は使用できません。 この値は、1 以上で、かつ開始指標 値を適用した後で 配列内に残っている要素の数以下でなければなりません。

一般に、%SUBARR は、索引のない配列が使用できる式であれば、どのような式でも有効です。 ただし、%SUBARR を以下の用途で使用することはできません。
  • 組み込み関数 %LOOKUPxx の配列引数として
  • 参照によって受け渡されるパラメーターとして
%SUBARR は、以下の方法で使用することができます。
  • EVAL または EVALR が使用されている代入の左側で使用する。 これにより、指定された配列内の指定された要素が変更されます。
  • 代入のターゲットである配列を含む、EVAL または EVALR が使用されている代入の右側の式で使用する。 これにより、配列の指定された要素の値が使用されるようになります。 配列要素が直接使用され、副配列の一時コピーは作成されません。
  • SORTA 命令の拡張演算項目 2 で使用する。
  • RETURN 命令の拡張演算項目 2 で使用する。
  • 対応するパラメーターが配列として定義されている場合に、VALUE または読み取り専用参照 (CONST キーワード) によって受け渡される。
  • %XFOOT 組み込み関数のパラメーターとして使用する。

詳細については、配列命令または 組み込み関数を参照してください。

図 1. %SUBARR を使用する
D a               s             10i 0 dim(5)
D b               s             10i 0 dim(15)
D resultArr       s             10i 0 dim(20)
D sum             s             20i 0
 /free  
     a(1)=9;
     a(2)=5;
     a(3)=16;
     a(4)=13;
     a(5)=3;
     // Copy part of an array to another array:
     resultArr = %subarr(a:4:n);     
          // this is equivalent to:
          //   resultArr(1) = a(4)
          //   resultArr(2) = a(5)
          //   ...
          //   resultArr(n) = a(4 + n - 1)

     // Copy part of an array to part of another array:
     %subarr(b:3:n) = %subarr(a:m:n);  
     // Specifying the array from the start element to the end of the array
     // B has 15 elements and A has 5 elements.  Starting from element 2
     // in array A means that only 4 elements will be copied to array B.
     // The remaining elements in B will not be changed.
       b = %subarr(a : 2);  

     // Sort a subset of an array:
     sorta %subarr(a:1:4);     
          // Now, A=(5 9 13 16 3);
          // Since only 4 elements were sorted, the fifth element
          // is out of order.
          // Using %SUBARR in an implicit array indexing assignment
     resultArr = b + %subarr(a:2:3)     
     // this is equivalent to:
     //   resultArr(1) = b(1) + a(2)
     //   resultArr(2) = b(2) + a(3)
     //   resultArr(3) = b(3) + a(4)

     // Using %SUBARR nested within an expression
     resultArr = %trim(%subst(%subarr(stringArr:i):j));
          // this is equivalent to:
          //   resultArr(1) = %trim(%subst(stringArr(i+0):j))
          //    resultArr(2) = %trim(%subst(stringArr(i+1):j))
          //   resultArr(3) = %trim(%subst(stringArr(i+2):j))

     // Sum a subset of an array
     sum = %xfoot (%subarr(a:2:3));     
          // Now sum = 9 + 13 + 16 = 38
図 2. 動的に割り振られる配列で %SUBARR を使用する
// Using %SUBARR with dynamically allocated arrays
D dynArrInfo      ds                  qualified
D   numAlloc                    10i 0 inz(0)
D   current                     10i 0 inz(0)
D   p                             *
D dynArr          s              5a   dim(32767) based(dynArrInfo.p)
D otherArray      s              3a   dim(10) inz('xy')
 /free 
     // Start the array with an allocation of five elements,
     // and with two current elements
     dynArrInfo.numAlloc = 5;
     dynArrInfo.p = %alloc(%size(dynArr) *
                    dynarrInfo.numAlloc);
     dynArrInfo.current = 2;
     // Initialize to blanks
     %subarr(dynArr : 1 : dynarrInfo.current) = *blank;

     // Set the two elements to some values
     dynArr(1) = 'Dog';
                     dynArr(2) = 'Cat';  

     // Sort the two elements
     sorta %subarr(dynArr : 1 : dynarrInfo.current);
          // dynArr(1) = 'Cat'
          // dynArr(2) = 'Dog'

     // Assign another array to the two elements
     otherArray(1) = 'ab';
     otherArray(2) = 'cd';
     otherArray(3) = 'ef';
     %subarr(dynArr : 1 : dynarrInfo.current) = otherArray;     
          // dynArr(1) = 'ab'
          // dynArr(2) = 'cd'

     // Changing the size of the array
     oldElems = dynArrInfo.current;
     dynArrInfo.current = 7;
     if (dynArrInfo.current > dynArrInfo.numAlloc);
          dynArrInfo.p = %realloc (dynArrInfo.p : dynArrInfo.current);
          dynArrInfo.numAlloc = dynArrInfo.current;
     endif;
     if (oldElems < dynArrInfo.current);     
          // Initialize new elements to blanks
         clear %subarr(dynArr : oldElems + 1 : dynArrInfo.current - oldElems);
     endif; 
注意:
配列の一部を同じ配列内の別の部分に割り当てるために %SUBARR を使用することができます。 ただし、その配列のソース部分が配列のターゲット部分とオーバーラップしている場合には、 予測不能な結果が生じる可能性があります。

詳細については、組み込み関数を参照してください。