ObjectScript のリスト
ここでは、ObjectScript のネイティブのリスト形式と代替手段の概要を示します。簡単な代替手段の 1 つとして、区切り文字列があります。クラスベースの代替手段もあります。
ネイティブのリスト形式
ObjectScript には、ネイティブのリスト形式が用意されています。$LIST 関数を使用してこれらのリストを操作するため、この形式は、$LIST 形式と呼ばれることがあります。
ネイティブのリスト形式の操作には、ObjectScript のリスト関数の使用のみがサポートされます。この種のリストの内部構造は文書化されていません。また、予告なしに変更される場合があります。
クラス定義で、プロパティにネイティブのリスト形式を使用させたい場合は、プロパティのタイプを %Library.ListOpens in a new tab または短い名前 %ListOpens in a new tab として宣言します。
リスト関数
ObjectScript のネイティブのリスト形式は、要素と呼ばれる部分文字列のエンコードされたリストで構成されます。これらのリストは、以下のリスト関数のみを使用して処理できます。
-
リスト作成 :
-
$LISTBUILD は、パラメータ値として各要素を指定することでリストを作成します。
-
$LISTFROMSTRING は、デリミタを含む文字列を指定することでリストを作成します。この関数はデリミタを使用して、文字列を要素に分割します。
-
$LIST は、既存のリストからその一部を抽出してリストを作成します。
-
-
リスト・データ取得 :
-
$LIST は、リスト要素の値をその位置別に返します。リストの先頭または末尾から位置をカウントできます。
-
$LISTNEXT は、リストの先頭から順番にリスト要素の値を返します。$LIST および $LISTNEXT はともにリストから要素を順番に返すために使用されますが、大量のリスト要素を返す場合は、$LISTNEXT の方が大幅に高速な処理が可能です。
-
$LISTGET は、リスト要素の値を位置別に返すか、または既定値を返します。
-
$LISTTOSTRING は、リストの要素の値すべてを区切り文字列として返します。
-
-
リストの操作 :
-
SET $LIST は、リストの要素を挿入、更新、または削除します。SET $LIST は、リストの要素または要素の範囲を 1 つ以上の値で置換します。SET $LIST はリストの要素を複数の要素で置換できるため、これを使用してリストに要素を挿入できます。SET $LIST はリストの要素を NULL 文字列で置換できるため、これを使用してリストの要素または要素の範囲を削除できます。
-
-
リストの評価: :
-
$LISTVALID は、文字列がリストに有効かどうかを判断します。
-
$LISTLENGTH は、リスト内の要素の数を判断します。
-
$LISTDATA は、指定のリスト要素がデータを含んでいるかどうか判断します。
-
$LISTFIND は、指定した値がリストにあるかどうかを判断して、リストの位置を返します。
-
$LISTSAME は、2 つのリストが同一かどうか判断します。
-
リストはエンコードされた文字列であるため、InterSystems IRIS ではリストの扱いが標準の文字列の場合とは多少異なります。したがって、リストでは標準の文字列関数を使用しないようにします。さらに、ほとんどのリスト関数は、標準の文字列で使用すると <LIST> エラーを発生します。
以下のプロシージャは、さまざまなリスト関数の使用法を示しています。
ListTest() PUBLIC {
// set values for list elements
SET Addr="One Memorial Drive"
SET City="Cambridge"
SET State="MA"
SET Zip="02142"
// create list
SET Mail = $LISTBUILD(Addr,City,State,Zip)
// get user input
READ "Enter a string: ",input,!,!
// if user input is part of the list, print the list's content
IF $LISTFIND(Mail,input) {
FOR i=1:1:$LISTLENGTH(Mail) {
WRITE $LIST(Mail,i),!
}
}
}
このプロシージャは、リストの重要な機能を示しています。
-
$LISTFIND は、テストされた値がリスト項目に一致する場合にのみ 1 (True) を返します。
-
$LISTFIND と $LISTLENGTH は式で使用します。
リスト関数の詳細は、"ObjectScript リファレンス" の関連リファレンス・ページを参照してください。
スパース・リストおよびサブリスト
リストの指定された位置に要素値を追加する関数では、適正位置に値を配置するために十分な数のリスト要素を追加します。以下に例を示します。
SET $LIST(Alphalist,1)="a"
SET $LIST(Alphalist,20)="t"
WRITE $LISTLENGTH(Alphalist)
この例にある 2 番目の $LIST で 20 番目のリスト要素を作成しているので、$LISTLENGTH は値 20 を返しますが、2 ~ 19 番目の要素には値が設定されていません。そのため、これらの値を表示させようとすると、<NULL VALUE> エラーが発生します。$LISTGET を使用して、このエラーを回避できます。
List の要素自体をリストとすることもできます。このようなサブリストから値を取得するには、以下のように $LIST 関数呼び出しを入れ子にします。
SET $LIST(Powers,2)=$LISTBUILD(2,4,8,16,32)
WRITE $LIST($LIST(Powers,2),5)
このコードは、Powers リストの 2 番目の要素に含まれるサブリストの 5 番目の要素値、32 を返します。(Powers リストで 2 番目のアイテムは、2 を 1 乗から 5 乗までしたサブリストです。したがって、例えばサブリストの最初のアイテムは、2 の 1 乗になります。)
リストの圧縮
ListFormat 設定は、$LIST のエンコードされた文字列に格納する際、Unicode 文字列を圧縮するかどうかを制御します。既定では、圧縮されません。圧縮された形式は、InterSystems IRIS によって自動的に処理されます。圧縮された形式がサポートされるかどうかを確認せずに、Java や C# などの外部クライアントに圧縮されたリストを渡さないでください。
%SYSTEM.ProcessOpens in a new tab クラスの ListFormat()Opens in a new tab メソッドを使用すると、プロセスごとの動作を制御できます。
Config.MiscellaneousOpens in a new tab クラスの ListFormatOpens in a new tab プロパティを設定するか、InterSystems IRIS の管理ポータルで [システム管理] から [構成]、[追加の設定]、[互換性] を選択して、システム全体の既定の動作を設定できます。
代替手段としての区切り文字列
ネイティブのリスト形式の簡単な代替手段として、デリミタ区切り文字列をリストとして使用できます。この場合、一般に以下の関数を使用します。
-
$PIECE — 指定の区切り文字に基づいて文字列内の特定の部分を返します。その範囲や、複数の区切り文字を元に、1 つの文字列から複数の個所を返すこともできます。
-
$LENGTH — 指定の区切り文字に基づいて 1 つの文字列にある構成要素の数を返します。
$PIECE 関数独自の重要な機能として、専用の区切り文字 (例えば ^) で区切って記述した複数の部分文字列を単一の文字列として使用できます。長い文字列はレコードとして、部分文字列はそのフィールドとして動作します。
$PIECE の構文は以下のとおりです。
WRITE $PIECE("ListString","QuotedDelimiter",ItemNumber)
ListString は使用されている完全なレコードを含む、引用符で囲まれた文字列です。QuotedDelimiter は指定の区切り文字で、引用符内に記述する必要があります。ItemNumber は、返されるように指定された部分文字列です。例えば以下の構文で、スペースで区切られた以下のリストで 2 番目のアイテムを表示します。
WRITE $PIECE("Kennedy Johnson Nixon"," ",2)
これは、Johnson を返します。
また、リストから複数の値を返すこともできます。以下はその構文です。
WRITE $PIECE("Nixon***Ford***Carter***Reagan","***",1,3)
これは、Nixon***Ford***Carter を返します。この値は、実際の部分文字列を参照する必要があります。また、3 番目の引数 (ここでは 1) は、4 番目の引数 (ここでは 3) よりも小さい値になる必要があることに注意してください。
以下のリストのように、区切り文字は任意に決めることができます。
SET x = $PIECE("Reagan,Bush,Clinton,Bush,Obama",",",3)
SET y = $PIECE("Reagan,Bush,Clinton,Bush,Obama","Bush",2)
WRITE x,!,y
これは、以下を返します。
Clinton
,Clinton,
最初のコードの区切り文字はコンマです。2 番目は、文字列 Bush が区切り文字であるため、返される文字列はコンマを含みます。区切り文字を正確に理解するために、次のセクションではリストに関連する関数を説明しています。
高度な $PIECE 関数
要素値を区切ってリストに記述する $PIECE を呼び出すことで、リストの中で固有の項目に部分文字列を配置し、他の部分は空として、十分な数の項目をリストに追加できます。例えば、あるコードで、リストの 1 番目、4 番目、そして 20 番目に項目を設定するとします。
SET $PIECE(Alphalist, "^", 1) = "a"
WRITE "First, the length of the list is ",$LENGTH(Alphalist,"^"),".",!
SET $PIECE(Alphalist, "^", 4) = "d"
WRITE "Then, the length of the list is ",$LENGTH(Alphalist,"^"),".",!
SET $PIECE(Alphalist, "^", 20) = "t"
WRITE "Finally, the length of the list is ",$LENGTH(Alphalist,"^"),".",!
この $LENGTH 関数は、1、4、20 の値を順番に返します。その長さに相当する必要な数のアイテムが、このコードで作成されているからです。ただし、アイテム 2、3、そして 5 から 19 には、値が設定されていません。そのため、これらの値を表示させようとしても、何も表示されません。
区切り文字列アイテムは、区切り文字列も含むことができます。このようなサブリストから値を取得するには、以下のように $PIECE 関数呼び出しを入れ子にします。
SET $PIECE(Powers, "^", 1) = "1::1::1::1::1"
SET $PIECE(Powers, "^", 2) = "2::4::8::16::32"
SET $PIECE(Powers, "^", 3) = "3::9::27::81::243"
WRITE Powers,!
WRITE $PIECE( $PIECE(Powers, "^", 2), "::", 3)
このコードは 2 行の出力を返します。1 行目は文字列 Powers で、すべての区切り文字を含みます。2 行目は 8 で、これは Powers の 2 番目の要素に含まれるサブリストの 3 番目の要素の値です。(Powers リストで、n 番目のアイテムは、2 を 1 乗から 5 乗までしたサブリストです。したがって、例えばサブリストの最初のアイテムは、n の 1 乗となります。)
詳細は、"$PIECE" を参照してください。
リストと区切り文字列の比較
区切り文字列と比較した場合、ネイティブのリスト形式には次のような利点があります。
-
ネイティブのリスト形式では、特定の区切り文字は不要です。$PIECE 関数では複数のデータ項目を含む文字列を管理できますが、これは専用の区切り文字としての文字 (または文字列) の設定にもよります。区切り文字を使用する場合は、データ項目の中にデータとして区切り文字が存在すると、データの区切り位置が混乱する可能性が常に存在しています。リストは区切り文字による混乱を避けるうえで効果的です。したがって、あらゆる文字または文字の組み合わせをデータとして入力できます。
-
データの要素は、$PIECE を使用して区切り文字列から取得するよりも、$LIST または $LISTNEXT を使用してリストから取得する方が高速です。データを順番に取得する場合は、$LIST よりも $LISTNEXT の方が大幅に高速ですが、双方とも $PIECE よりはきわめて高速です。
ネイティブのリスト形式と比較した場合、区切り文字列にはさまざまな利点があります。
-
区切り文字列では、$FIND 関数を使用して、より柔軟なデータ内容の検索ができます。$LISTFIND は、完全一致を必要とするので、リストの部分一致文字列を検索できません。したがって、上記の例では、アドレス One Memorial Drive が文字 One で始まっているにもかかわらず、$LISTFIND を使用してメール・リストの文字列 One を検索しても 0 (失敗を示す) が返されます。
-
区切り文字列は標準文字列であるので、標準文字列関数をすべて使用できます。ネイティブのリストはエンコードされた文字列なので、このリストでは $List 関数のみが使用できます。
クラスベースのリスト
ネイティブのリスト形式や区切り文字列ではなく、別の構造を使用し、オブジェクトベースの API を提供するリスト・クラスを使用できます。InterSystems IRIS では、リスト形式のクラス・プロパティとして使用できる一連のクラスや、スタンドアロン・リストに使用できる別の一連のクラスを提供しています。