Category:LSL リスト - Second Life Wiki

Category:LSL リスト

From Second Life Wiki

Second Life Wiki > LSL リスト (Redirected from List/ja)
Jump to: navigation, search

リストはゼロ個以上の要素を扱える特殊なデータ型です。

リストはその要素を角括弧で囲んで表記します。各要素はカンマで区切られます。

例:

[0,1,2,3,4]
 
["Yes","No","Perhaps"]

(注意: 他のプログラミング言語の経験者向けに付け加えると、LSL には配列は無く、リストだけがあります。)


Diverse Data Types 様々なデータ型

必ずしもリストの全要素が同じデータ型である必要はありません。あるリストの中に、tring 型、integer 型、float 型、vector 型などの要素を並存させる事ができます。

例: //integer 型、float 型、string 型、vector 型の要素を含んだリスト

[1,14.154,"Isn't this fun?",<0,0,0>]

しかし、リストを別のリストの要素とすることはできません。(すなわち、リストの入れ子はできません。)

[1, "one", 2, "two"] + [3, "three"] の結果は [1, "one", 2, "two", 3, "three"] であり、
[1, "one", 2, "two", [3, "three"]] ではありません。

リストに要素を追加する際、追加要素のデータ型をリストは自動的に記憶します。

通常、あなたはリストに要素を追加した当人なのですから、リストのどこにどんな型のデータがあるか知っているはずです。そしてそれを適切な List2<type> 関数、すなわち llList2StringllList2Vector など (後述) を使いリストから取り出せます。

しかし、もし何らかの理由でリスト要素のデータ型を確認したい場合は、llGetListEntryType 関数を使えます。

注意: リストに float 型のデータを加える場合、型を確実に保持するためにも、小数点付き (例えば 1 でなく 1.0) にしてください。

リストは string 型へ直接、型キャストできます。

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>
    }
}



リスト内の位置と、リストの長さの数え方

まず最初に、以下の点に注意するのが大切です。(経験者でも疲れていると躓くポイントです。)

["Yes","No","Perhaps"]

リストの要素は 3 個なので、リストの長さは 3 です。リストの長さは llGetListLength 関数で返されます。

integer length = llGetListLength(mylist);

しかし、リスト内の要素の位置 (いわゆる "インデックス") は 0 から数え始めます。-- 1 ではありません。

上の例の "Yes" の位置は 0、"No" は 1、"Perhaps" は 2 です。

従って、リストに要素が 7 個あったとしたら、最後の要素の位置は 6 です。

ゆえに、事前に位置を知らずとも、最後の要素は以下のように取得できます。

integer length = llGetListLength(mylist);
string item = llList2String(myList,length - 1);


リストの制限

スクリプトが実行されている間、リストは必要に応じて動的に大きくなりえます。そのサイズは、スクリプトが利用可能なメモリの量で決まります。

ただしコンパイル時 (保存時) には、スクリプトにハード コードされた定義済リストは最大 72 個の要素しか持てないという制限があります。例えば多くのカラー バリエーションを用意するといった場合などは、こうした非常に長い定義済みリストがあり得ます。

注意: 定義済みリストとしてどうしても 72 個を超える要素を使いたいという場合は、コンパイラが対応できるよう 2 個以上のリストに分割しておき、state_entry イベントなり適切なタイミングでそれを結合してください。

biggerlist = biglist01 + biglist02;


リストへの要素の追加

既存のリストに要素を追加する方法には 6 通りあります:

  1. myList = myList + [new_item];
  2. myList += [new_item];
  3. myList = (myList=[]) + myList + [new_item];
  4. myList = myList + new_item;
  5. myList += new_item;
  6. myList = (myList=[]) + myList + new_item;

注意

  • 1 と 2 のコンパイル結果は同じです。
  • 4 と 5 のコンパイル結果は同じです。
  • 4, 5, 6 はそれぞれ 1, 2, 3 に比べてバイト コードが少なく済みますが、LSO-LSL VM のバグによって string 型と key 型間の型キャストが期待通りに行なわれません: SVC-1710[c]
  • LSO-LSL において、3, 6 は 1, 2, 4, 5 に比べると非常にメモリの節約となります。(無駄な空きメモリの原因となるフラグメントを、ヒープ領域で抑制できます。) Mono-LSL においては、殆ど有利/不利といった違いはありません。
    • (LSO-LSL において) 状況によっては、この手法になんら効果が無い場合もあります。はっきりしない場合は、この手法を使った場合/使わない場合それぞれを検証してください。

リストの結合

リストは + 記号で単純に結合できます。

newlist = list01 + list02;
 
newlist = list01 + ["red","brown",<0,0,0>];

注意: 上の例では、結果としては 1 個のリストになりますが、実際は処理中に 3 個のリストがメモリに作成されます。これはメモリ使用量に影響する場合があります。


リストを空にする

リストを空にする場合は、以下のように空の角括弧を等号で代入してください:

myList = [];


飛び石リスト (ストライド リスト)

リストの一般的な使われ方のひとつに、データの構造的な集積 (いわゆる構造体) の機能を模倣するという点があります。構造体は、多くのプログラミング言語で使用可能ですが、LSL では扱えません。

(2008年7月時点の) SL で、ある種の構造と共にある程度の量のデータを保存するのに使える最もよい手段が、データの扱いに制約は多いですが、飛び石リスト (ストライド リスト) です。

飛び石リストには、それぞれグループ化 (ストライド化) された、関連データ構成を保存できます。

ここでは例で示すのが良いでしょう。アバターの集団について、各人の名前、性別、誕生日を記録するのに飛び石リストを使えます:

list demographics = ["John Adams", "male", "2007-06-22", "Shirley Bassey", "female", "2005-11-02", "Matt Damon", "male", "2008-05-19"];

この例は、各グループ (ストライド) が 3 個のデータ要素 (名前・性別・誕生日) を持つので、3 要素からなるストライドを持つといえます。0 番目のデータ ("John Adams") は最初のグループの先頭で、3 番目のデータ ("Shirley Bassey") は二番目のグループの先頭、といった具合です。

重要なのは、各グループの各要素は、リストの中で常に同じ順番を保たなければいけないという事です。上の例ならば、三要素のうち名前は常に先頭になければいけません。リストをソートする llListSort 関数はグループの先頭要素しかソートしませんので、記録する情報の順番を注意深く考慮すべきです。言い換えると、アバターの誕生日がスクリプトの処理で最も重要な属性という場合、それを先頭に持ってきて、名前を二番目にする必要があるでしょう。アバターをファースト ネームでなくラスト ネームで並び替えられるようにしたい場合、LastName FirstName という形式で名前をリストに追加すべきです。(カンマが無いのは、ラスト ネームとファースト ネームを別要素にしないという例だからです。)

上のリストに別の人を追加するには、以下のようにします:

demographics += ["Dorthy Lamour", "female", "2010-01-22"];


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 関数へ渡す際などに役立ちます。