公開技術情報

[English] [Japanese]

04.2. Set 編

ここでは LuneScript の値の集合 Set の扱いについて説明します。

Set と Map の違い

Set は値の集合を管理し、 Map は値と値の紐付けを管理します。

どちらも Lua に変換した場合、テーブルとして管理するため、 Map よりも Set を使った方が実行速度やメモリ面で優位ということはありません。

しかし、Map ではなく Set を使うことで、次の効果があります。

  • データの用途が明確になる
  • 無駄に Map の value を扱う必要がない
  • リテラルな値が書き易い

次の点において Set と Map は同じです。

  • 格納する値の順序を保持しません。
  • nilable は格納できません。

Set のコンストラクタ

Set は次のように書くことでデータを生成します。

// @lnsFront: ok
let obj = (@ 1, 2, 3, 4 ); // 1 2 3 4

これは、1,2,3,4 のデータを保持する Set です。

Set は (@ ) で値を括ります。

なお、上記処理は型推論により型宣言を省略していますが、 省略しない場合は次のように書きます。

// @lnsFront: ok
let obj:Set<int> = (@ 1, 2, 3, 4 ); // 1 2 3 4

Set<int> は、要素が int である Set を宣言します。

空の Set を使用する場合は、型推論できないため型を明示する必要があります。

// @lnsFront: ok
let obj:Set<int> = (@);

Set の操作

次の操作をサポートします。

  • 追加

    • add()
  • 削除

    • del()
  • 有無確認

    • has()
  • 要素数取得

    • len()
  • 複製

    • clone()

Set への値の追加、削除は次のように行ないます。

// @lnsFront: ok
let mut obj = (@ 1, 2, 3, 4 );
obj.add( 0 );  // 0 1 2 3 4
obj.del( 2 );  // 0 1 3 4

Set で管理する値の有無確認は、次のように行ないます。

// @lnsFront: ok
let obj = (@ 1, 2, 3, 4 );
print( obj.has( 0 ) );  // false
print( obj.has( 1 ) );  // true

Set は、 len() メソッドで要素の数を取得できます。 ただし、 len() メソッドは要素を列挙して数を計算するため、計算量はサイズに比例します。

// @lnsFront: ok
let mut obj = (@ 1, 2, 3, 4 );
print( obj.len() );

同じ Set を生成するには clone() を使用します。

// @lnsFront: ok
let obj = (@ 1, 2, 3, 4 );
let obj2 = obj.clone();

clone は、要素を shallow コピーします。

Set 間の操作

次の操作をサポートします。

  • 合成

    • or()
    • 二つの集合の和を残す
  • 共通

    • and()
    • 二つの集合の共通部分を残す
  • 差分

    • sub()
    • 現在の集合から引数の集合と共通しない部分を残す

なお、この操作は対象の Set の内容を書き変えます。

// @lnsFront: ok
let set1 = (@  1, 2, 3 );
let set2 = (@  2, 3, 4 );
let set3 = set1.clone().or(set2);   // 1 2 3 4
let set4 = set1.clone().and(set2);  // 2 3 
let set5 = set1.clone().sub(set2);  // 1