SORTA (配列の分類)

自由形式構文 SORTA{(A/D) } 配列名 | キー付きデータ構造配列
SORTA{(A/D) } %SUBARR(配列名 | キー付きデータ構造配列: 開始要素 { : 要素の数 })
コード 演算項目 1 拡張演算項目 2
SORTA(A/D)   配列またはキー付きデータ構造配列
    %SUBARR(配列またはキー付きデータ構造配列 : 開始要素 {:要素の数 } )

スカラー配列の場合、配列名 オペランドは、ソートされる配列の名前です。 配列 *IN を指定することはできません。配列が交互形式のデータを持つコンパイル時配列または実行時前配列の場合に は、交互配列は分類されません。 配列名 として指定された配列だけが分類されます。

配列データ構造の場合、キー付きデータ構造配列 オペランドは、ソート対象配列からなる修飾名の後に、 ソートのキーとして使用するサブフィールドを指定したものです。 ソート対象の配列データ構造は、配列の指標として * を指定して示します。 例えば、配列データ構造 INFO にサブフィールド NAME と SALARY がある場合、 サブフィールド NAME をキーとして使用して配列 INFO をソートするには、 SORTA のオペランドとして INFO(*).NAME を指定します。 配列 INFO を SALARY でソートするには、SORTA のオペランドとして INFO(*).SALARY を指定します。

配列の定義仕様書の ASCEND キーワードまたは DESCEND キーワードで配列の順序が定義されている場合、 配列は常にその順でソートされます。 配列の順序を指定しないと、順序はデフォルトで昇順になります。 命令拡張の 'A' が指定されている場合、配列は昇順でソートされます。 命令拡張の 'D' が指定されている場合、配列は降順でソートされます。

注: ASCEND キーワードと DESCEND キーワードは、配列データ構造に指定できません。

配列が OVERLAY キーワードを指定して定義されていて、命令拡張の 'A' または 'D' が指定されていない場合には、基本配列はオーバーレイ配列によって定義された順序でソートされます。

図形配列および UCS-2 配列は、代替照合順序に関係なく、定義仕様書に指定された順序で、 配列要素の 16 進数値によってソートされます。

配列の部分をソートするには、%SUBARR 組み込み関数を使用してください。

注:
  1. 配列を分類すると前の順序は保存されません。 例えば、別のオーバーレイ配列を使用して配列を 2 回分類すると、最終順序 は最後の分類の順序となります。 分類の順序が同じで 16 進数値が (例えば、代替照合順序または順序を決定 するオーバーレイ配列を使用したために) 異なる要素は、分類後に前と同じ順 序にならないことがあります。
  2. 基底ポインターの配列を分類する場合には、配列のすべての値が同じ空間内 のアドレスであることを確認しなければなりません。 そうでない場合には、結果に整合性がなくなる場合があります。 詳しくは、比較命令を参照してください。
  3. ヌル値可能配列が分類される場合、その分類では、ヌル・フラグの設定値は 考慮に入れられません。
  4. すべての定義済み要素が割り振り済みでない動的割り振り配列に 対する分類によって、エラーが発生する可能性があります。%SUBARR 組み込み関数を使用して、ソートを割り振り済み要素のみに限定してください。
  5. DESCEND キーワードを指定して定義された配列のソートでは、命令拡張 'A' を使用できません。 また、ASCEND キーワードを指定して定義された配列のソートでは、命令拡張 'D' を使用できません。
  6. 配列データ構造をソートするとき:
    1. 修飾名で指標 (*) より前の部分は、配列を表す必要があります。 また、(*) より後の部分は、スカラー・サブフィールドまたは指標付きスカラー配列を表す必要があります。
    2. 複合修飾名に複数の配列サブフィールドがある場合には、1 つの配列サブフィールドしかソートできません。 修飾名にあるその他の配列ではすべて、指標の指定が必要です。 例えば、配列データ構造 FAMILY に配列サブフィールド CHILD があり、 CHILD の要素に配列サブフィールド PET があり、PET サブフィールドにサブフィールド NAME がある場合、FAMILY、CHILD、および PET のいずれか 1 つの配列でしか、1 つの SORTA 命令でソートできません。 配列 CHILD をソートする場合には、FAMILY と PET の配列に明示的な指標が必要になります。 SORTA の有効なオペランドの例として、FAMILY(i).CHILD(*).PET(1).NAME があります。 この SORTA 命令では、FAMILY(i) の配列 CHILD を PET(1) のサブフィールド NAME でソートします。
    3. 配列データ構造は、命令拡張 'D' が指定されない限り、キーの昇順でソートされます。
    4. ソート・キーが順序配列の要素である場合、配列データ構造のソート時にその順序は考慮されません。

詳細については、配列命令を参照してください。

図 1. SORTA 命令
*...1....+....2....+....3....+....4....+....5....+....6....+....7...+....
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++
DARRY             S              1A   DIM(8) ASCEND
DARRY2            S              1A   DIM(8)
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....
 *
 *  The SORTA operation sorts ARRY into ascending sequence because
 *  the ASCEND keyword is specified.
 *  If the unsorted ARRY contents were GT1BA2L0, the sorted ARRY
 *  contents would be ABGLT012.
C                   SORTA     ARRY

 *  The SORTA operation sorts ARRY2 into descending ascending sequence
 *  the (D) operation extender is specified.
 *  If the unsorted ARRY2 contents were GT1BA2L0, the sorted ARRY2
 *  contents would be 210TLGBA.
C                   SORTA(D)  ARRY2
図 2. OVERLAY による SORTA 命令
*...1....+....2....+....3....+....4....+....5....+....6....+....7...+....
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++
 * In this example, the base array has the values aa44 bb33 cc22 dd11
 * so the overlaid array ARRO has the values 44 33 22 11.
D                 DS
D ARR                            4    DIM(4) ASCEND
D ARRO                           2    OVERLAY(ARR:3)
D
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....
C
 * After the SORTA operation, the base array has the values
 * dd11 cc22 bb33 aa44
C
C                   SORTA     ARRO
図 3. 昇順または降順の SORTA 命令
 * The names array does not have a sequence keyword
 * (ASCEND or DESCEND) specified.D info            DS                  QUALIFIED
D   names                       10A   DIM(2)

 /free

    // Initialize the array    info.names(1) = 'Bart';
    info.names(2) = 'Lisa';

    // Sort the info.names in descending order    SORTA(D) info.names;
    // info.names(1) = 'Lisa'
    // info.names(2) = 'Bart'

    // Sort the info.names in ascending order    SORTA(A) info.names;
    // info.names(1) = 'Bart'
    // info.names(2) = 'Lisa'

    // With no operation extender, it defaults to ascending order    SORTA info.names;
    // info.names(1) = 'Bart'
    // info.names(2) = 'Lisa'
図 4. 配列データ構造での SORTA 命令
D emp             DS                  QUALIFIED DIM(25)
D   name                        25A   VARYING
D   salary                       9P 2
D numEmp          S             10I 0

// Initialize the data structureemp(1).name = 'Maria';
emp(1).salary = 1100;
emp(2).name = 'Pablo';
emp(2).salary = 1200;
emp(3).name = 'Bill';
emp(3).salary = 1000;
emp(4).name = 'Alex';
emp(4).salary = 1300;
numEmp = 4;

// Sort the EMP array using the NAME subfield as a keySORTA %subarr(emp(*).name : 1 : numEmp);
// emp(1).name = 'Alex'       <-----
// emp(1).salary = 1300
// emp(2).name = 'Bill'       <-----
// emp(2).salary = 1000
// emp(3).name = 'Maria'      <-----
// emp(3).salary = 1100
// emp(4).name = 'Pablo'      <-----
// emp(4).salary = 1200

// Sort the EMP array using the SALARY subfield as a keySORTA %subarr(emp(*).salary : 1 : numEmp);
// emp(1).name = 'Bill'
// emp(1).salary = 1000       <-----
// emp(2).name = 'Maria'
// emp(2).salary = 1100       <-----
// emp(3).name = 'Pablo'
// emp(3).salary = 1200       <-----
// emp(4).name = 'Alex'
// emp(4).salary = 1300       <-----

// Sort the EMP array descending using the SALARY subfieldSORTA(D) %subarr(emp(*).salary : 1 : numEmp);
// emp(1).name = 'Alex'
// emp(1).salary = 1300       <-----
// emp(2).name = 'Pablo'
// emp(2).salary = 1200       <-----
// emp(3).name = 'Maria'
// emp(3).salary = 1100       <-----
// emp(4).name = 'Bill'
// emp(4).salary = 1000       <-----
図 5. 複合配列データ構造での SORTA 命令
D emp_t           DS                  QUALIFIED TEMPLATE
D   name                        25A   VARYING
D teams           DS                  QUALIFIED DIM(2)
D   manager                     25A   VARYING
D   emps                              LIKEDS(emp_t) DIM(2)

// Initialize the data structureteams(1).manager = 'Jack';
teams(1).emps(1).name = 'Yvonne';
teams(1).emps(2).name = 'Mary';
teams(2).manager = 'Ann';
teams(2).emps(1).name = 'Wendy';
teams(2).emps(2).name = 'Thomas';

// Sort the TEAMS array using the MANAGER subfield as a keySORTA teams(*).manager;
//    teams(1).manager = 'Ann'           <-----
//    teams(1).emps(1).name = 'Wendy'
//    teams(1).emps(2).name = 'Thomas'
//    teams(2).manager = 'Jack'          <-----
//    teams(2).emps(1).name = 'Yvonne'
//    teams(2).emps(2).name = 'Mary'

// Sort the TEAMS array using the EMPS(2).NAME subfield as a keySORTA teams(*).emps(2).name;
//    teams(1).manager = 'Jack'
//    teams(1).emps(1).name = 'Yvonne'
//    teams(1).emps(2).name = 'Mary'     <-----
//    teams(2).manager = 'Ann'
//    teams(2).emps(1).name = 'Wendy'
//    teams(2).emps(2).name = 'Thomas'   <-----

// Sort the TEAMS(1).EMPS array using the NAME subfield as a keySORTA teams(1).emps(*).name;
//    teams(1).manager = 'Jack'
//    teams(1).emps(1).name = 'Mary'     <-----
//    teams(1).emps(2).name = 'Yvonne'   <-----
//    teams(2).manager = 'Ann'
//    teams(2).emps(1).name = 'Wendy'
//    teams(2).emps(2).name = 'Thomas'

// Sort the TEAMS array first by the MANAGER subfield
// and then by the EMPS.NAME subfieldsSORTA teams(*).manager;
for i = 1 to %ELEM(TEAMS);
   SORTA teams(i).emps(*).name;
endfor;
// After the first sort, by MANAGER:
//    teams(1).manager = 'Ann'           <-----
//    teams(1).emps(1).name = 'Wendy'
//    teams(1).emps(2).name = 'Thomas'
//    teams(2).manager = 'Jack'          <-----
//    teams(2).emps(1).name = 'Mary'
//    teams(2).emps(2).name = 'Yvonne'
// After loop with the second sort, by EMPS.NAME:
//    teams(1).manager = 'Ann'
//    teams(1).emps(1).name = 'Thomas'   <----- 1
//    teams(1).emps(2).name = 'Wendy'    <----- 1
//    teams(2).manager = 'Jack'
//    teams(2).emps(1).name = 'Mary'     <----- 2
//    teams(2).emps(2).name = 'Yvonne'   <----- 2