Category:LSL List/ja

From Second Life Wiki
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
  • 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 関数が飛び石リストを扱えます:

The function llListStatistics can, with care, be used for strided lists as it will silently ignore non integer and non float items.

以下はユーザが作成し追加した、飛び石リスト用の関数です。

関数 説明
ListStridedMove 飛び石リストのある要素を、リスト内の別の場所へ移動します。
ListStridedRemove 飛び石リストの一部を削除します。
ListStridedUpdate 飛び石リストの一部を更新します。
ListStridedReorder Reorder the contents of every stride or reorder entire strides.

応用的なリスト操作

以下は、組み込み LSL 関数では対応できない処理を行なうため LSL ユーザによって作成、提供された関数です。


関数 説明
ListCast 要素の型を統一するようリストを処理します。
List_cast Processes a list so that its contents are converted from strings to their respective types.
ListCompare 二つのリストの異同を評価します。
ListItemDelete リストからひとつの要素を削除します。
ListKeyCase Changes the values of the whole list into uppercase or lowercase based on input
ListToWholeNumbers float 型データのリストを、integer 型データのリストへ変換します。
ListXorY 二つのリストを連結します。ただし、要素の重複は排除します。
ListXandY 二つのリストを評価し、双方で共通する要素だけ返します。
ListXnotY リスト X に有り、リスト Y に無い要素だけ返します。
ListXxorY リストの片方にだけある要素を返します。重複した要素は、一方だけ除かれるのでなく、両方とも除かれます。
ListXequY 二つのリストが同一かどうか評価します。
ListXneqY 二つのリストが不一致かどうか評価します。
Replace リストの中の指定した要素を、一つだけ別の指定要素に置き換えます。
Replace All 'src list' において、'from list' に該当する要素を全て 'to list' に変換します。上の変換関数ほど単純ではありませんが、複数の要素を一度に処理できます。
ListUnique リストの中で一度だけ出現する要素を返します。
ccFixListDatatypes リストの各要素を適切に型キャストして返します。文字列から切り分けたリストを llSetPrimitiveParams 関数へ渡す際などに役立ちます。
2D Pseudo-Array A way to emulate the behavior of a 2 dimensional array.