Category:LSL リスト
LSL ポータル | 関数 | イベント | 型 | 演算子 | 定数 | 実行制御 | スクリプトライブラリ | カテゴリ別スクリプトライブラリ | チュートリアル |
リストはゼロ個以上の要素を扱える特殊なデータ型です。
リストはその要素を角括弧で囲んで表記します。各要素はカンマで区切られます。
例: <lsl>[0,1,2,3,4]
["Yes","No","Perhaps"]</lsl>
(注意: 他のプログラミング言語の経験者向けに付け加えると、LSL には配列は無く、リストだけがあります。)
Diverse Data Types
様々なデータ型
必ずしもリストの全要素が同じデータ型である必要はありません。あるリストの中に、tring 型、integer 型、float 型、vector 型などの要素を並存させる事ができます。
例: //integer 型、float 型、string 型、vector 型の要素を含んだリスト <lsl>[1,14.154,"Isn't this fun?",<0,0,0>]</lsl>
しかし、リストを別のリストの要素とすることはできません。(すなわち、リストの入れ子はできません。)
<lsl>[1, "one", 2, "two"] + [3, "three"] の結果は [1, "one", 2, "two", 3, "three"] であり、</lsl> <lsl>[1, "one", 2, "two", [3, "three"]] ではありません。</lsl>
リストに要素を追加する際、追加要素のデータ型をリストは自動的に記憶します。
通常、あなたはリストに要素を追加した当人なのですから、リストのどこにどんな型のデータがあるか知っているはずです。そしてそれを適切な List2<type> 関数、すなわち llList2String、llList2Vector など (後述) を使いリストから取り出せます。
しかし、もし何らかの理由でリスト要素のデータ型を確認したい場合は、llGetListEntryType 関数を使えます。
注意: リストに float 型のデータを加える場合、型を確実に保持するためにも、小数点付き (例えば 1 でなく 1.0) にしてください。
リストは string 型へ直接、型キャストできます。 <lsl>default {
touch_start(integer total_number) { list a = ["abc",1,2,3.14,<0,0,0>]; llOwnerSay((string)a); // outcom: abc123.140000<0.000000, 0.000000, 0.000000> }
}</lsl>
リスト内の位置と、リストの長さの数え方
まず最初に、以下の点に注意するのが大切です。(経験者でも疲れていると躓くポイントです。)
<lsl>["Yes","No","Perhaps"]</lsl>
リストの要素は 3 個なので、リストの長さは 3 です。リストの長さは llGetListLength 関数で返されます。
<lsl>integer length = llGetListLength(mylist);</lsl>
しかし、リスト内の要素の位置 (いわゆる "インデックス") は 0 から数え始めます。-- 1 ではありません。
上の例の "Yes" の位置は 0、"No" は 1、"Perhaps" は 2 です。
従って、リストに要素が 7 個あったとしたら、最後の要素の位置は 6 です。
ゆえに、事前に位置を知らずとも、最後の要素は以下のように取得できます。
<lsl>integer length = llGetListLength(mylist); string item = llList2String(myList,length - 1);</lsl>
リストの制限
スクリプトが実行されている間、リストは必要に応じて動的に大きくなりえます。そのサイズは、スクリプトが利用可能なメモリの量で決まります。
ただしコンパイル時 (保存時) には、スクリプトにハード コードされた定義済リストは最大 72 個の要素しか持てないという制限があります。例えば多くのカラー バリエーションを用意するといった場合などは、こうした非常に長い定義済みリストがあり得ます。
注意: 定義済みリストとしてどうしても 72 個を超える要素を使いたいという場合は、コンパイラが対応できるよう 2 個以上のリストに分割しておき、state_entry イベントなり適切なタイミングでそれを結合してください。
<lsl>biggerlist = biglist01 + biglist02;</lsl>
リストへの要素の追加
既存のリストに要素を追加する方法には 6 通りあります:
- myList = myList + [new_item];
- myList += [new_item];
- myList = (myList=[]) + myList + [new_item];
- myList = myList + new_item;
- myList += new_item;
- myList = (myList=[]) + myList + new_item;
注意
- 1 と 2 のコンパイル結果は同じです。
- 4 と 5 のコンパイル結果は同じです。
- 4, 5, 6 はそれぞれ 1, 2, 3 に比べてバイト コードが少なく済みますが、LSO-LSL VM のバグによって string 型と key 型間の型キャストが期待通りに行なわれません: SVC-1710
- LSO-LSL において、3, 6 は 1, 2, 4, 5 に比べると非常にメモリの節約となります。(無駄な空きメモリの原因となるフラグメントを、ヒープ領域で抑制できます。) Mono-LSL においては、殆ど有利/不利といった違いはありません。
- (LSO-LSL において) 状況によっては、この手法になんら効果が無い場合もあります。はっきりしない場合は、この手法を使った場合/使わない場合それぞれを検証してください。
リストの結合
リストは + 記号で単純に結合できます。
<lsl>newlist = list01 + list02;
newlist = list01 + ["red","brown",<0,0,0>];</lsl>
注意: 上の例では、結果としては 1 個のリストになりますが、実際は処理中に 3 個のリストがメモリに作成されます。これはメモリ使用量に影響する場合があります。
リストを空にする
リストを空にする場合は、以下のように空の角括弧を等号で代入してください:
<lsl>myList = [];</lsl>
飛び石リスト (ストライド リスト)
リストの一般的な使われ方のひとつに、データの構造的な集積 (いわゆる構造体) の機能を模倣するという点があります。構造体は、多くのプログラミング言語で使用可能ですが、LSL では扱えません。
(2008年7月時点の) SL で、ある種の構造と共にある程度の量のデータを保存するのに使える最もよい手段が、データの扱いに制約は多いですが、飛び石リスト (ストライド リスト) です。
飛び石リストには、それぞれグループ化 (ストライド化) された、関連データ構成を保存できます。
ここでは例で示すのが良いでしょう。アバターの集団について、各人の名前、性別、誕生日を記録するのに飛び石リストを使えます:
<lsl>list demographics = ["John Adams", "male", "2007-06-22", "Shirley Bassey", "female", "2005-11-02", "Matt Damon", "male", "2008-05-19"];</lsl>
この例は、各グループ (ストライド) が 3 個のデータ要素 (名前・性別・誕生日) を持つので、3 要素からなるストライドを持つといえます。0 番目のデータ ("John Adams") は最初のグループの先頭で、3 番目のデータ ("Shirley Bassey") は二番目のグループの先頭、といった具合です。
重要なのは、各グループの各要素は、リストの中で常に同じ順番を保たなければいけないという事です。上の例ならば、三要素のうち名前は常に先頭になければいけません。リストをソートする llListSort 関数はグループの先頭要素しかソートしませんので、記録する情報の順番を注意深く考慮すべきです。言い換えると、アバターの誕生日がスクリプトの処理で最も重要な属性という場合、それを先頭に持ってきて、名前を二番目にする必要があるでしょう。アバターをファースト ネームでなくラスト ネームで並び替えられるようにしたい場合、LastName FirstName という形式で名前をリストに追加すべきです。(カンマが無いのは、ラスト ネームとファースト ネームを別要素にしないという例だからです。)
上のリストに別の人を追加するには、以下のようにします:
<lsl>demographics += ["Dorthy Lamour", "female", "2010-01-22"];</lsl>
SL 以外のデータベースや表計算ソフトで使えるような、スマートなデータ分析やデータ操作を、飛び石リストでは何ら使えません。しかし外部の補助ツールが使えない状況ならば、SL でのある種の限定的な用途には合うでしょう。
飛び石リストを扱えるツールを紹介します:
(2008年7月時点で) 以下の 3 つの組み込み LSL 関数が飛び石リストを扱えます:
以下はユーザが作成し追加した、飛び石リスト用の関数です。
function | purpose |
---|---|
ListStridedMove | 飛び石リストのある要素を、リスト内の別の場所へ移動します。 |
ListStridedRemove | 飛び石リストの一部を削除します。 |
ListStridedUpdate | 飛び石リストの一部を更新します。 |
応用的なリスト操作
以下は、組み込み LSL 関数では対応できない処理を行なうため LSL ユーザによって作成、提供された関数です。
function | purpose |
---|---|
ListCast | 要素の型を統一するようリストを処理します。 |
ListCompare | 二つのリストの異同を評価します。 |
ListItemDelete | リストからひとつの要素を削除します。(llDeleteSubListと違い、番号ではなく要素そのものを指定できます。) |
ListToWholeNumbers | float 型データのリストを、integer 型データのリストへ変換します。 |
ListXorY | 二つのリストを連結します。ただし、要素の重複は排除します。 |
ListXandY | 二つのリストを評価し、双方で共通する要素だけ返します。 |
ListXnotY | リスト X に有り、リスト Y に無い要素だけ返します。 |
ListXxorY | リストの片方にだけある要素を返します。重複した要素は、一方だけ除かれるのでなく、両方とも除かれます。 |
ListXequY | 二つのリストが同一かどうか評価します。 |
ListXneqY | 二つのリストが不一致かどうか評価します。 |
Replace | リストの中の指定した要素を、一つだけ別の指定要素に置き換えます。 |
Replace All | 'src list' において、'from list' に該当する要素を全て 'to list' に変換します。上の変換関数ほど単純ではありませんが、複数の要素を一度に処理できます。 |
ListUnique | リストの中で一度だけ出現する要素を返します。 |
ccFixListDatatypes | リストの各要素を適切に型キャストして返します。文字列から切り分けたリストを llSetPrimitiveParams 関数へ渡す際などに役立ちます。 |
This category currently contains no pages or media.