Algodooでは、Thyme(タイム)と呼ばれる独自のスクリプト言語を使用します。
デフォルトで埋め込み(ビルトイン)関数も用意されていますが、追加の関数(function)を定義してあげることで、より便利に使うことができます。
本記事は、こちらの英語ドキュメント(Thyme Additional Functions)から、使用頻度が高そうな関数に絞って解説します。
完全に主観で選んでいますので、全体を知りたい場合は、こちらの英語ドキュメントを参照ください。
埋め込み(ビルトイン)関数
Algodooのシーンを開き、F10を押してコンソールを起動します。
タブキーを入力することで、埋め込み関数一覧を表示することができます。

入力補完にも対応していますので、例えば「math.p」までを入力して、タブキーを押すと、候補となる関数(この場合はmath.pi, math.posivate, math.powが出力される結果となります。

math.pow(2, 10)と入力して実行すると、2の10乗の結果が得られます。

Scene.myスコープ
以下の追加関数は、いずれもScene.myではじまるスコープに保存されます。
同様にScene.myと入力して、タブキーを押すと、候補となる変数や関数が一覧で表示されます。

リスト操作(List manipulation)
これらはF10を押したコンソール上から実行することを想定しています。
一度実行すると、開いているシーンのScene.my.<関数名>で保存されますので、毎回実行する必要はありません。
all
リスト内のすべての要素が指定された条件を満たす場合は true を返します。
- 使用法: Scene.my.all(<リスト>, <条件>)
- 例: Scene.my.all([1,2,3], (number)=>{number > 0 })はtrueを返す(リスト内のすべての数値が 0 より大きいため)
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
<条件> | 関数 | 各要素をチェックする条件 boolを返す必要がある |
Scene.my.all := (list, predicate)=>{
listLength := string.length(list);
if_then_else(listLength == 0, {
true;
}, {
if_then_else(predicate(list(0)), {
Scene.my.all(list(1 .. (listLength - 1)), predicate);
}, {
false;
});
});
};
any
リスト内のいずれかの要素が指定された条件を満たす場合は true を返します。
- 使用法: Scene.my.any(<リスト>, <条件>)
- 例: Scene.my.any([-3,0], (number)=>{number > 0 })はfalseを返す(リスト内の数字はどれも 0 より大きくないため)
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
<条件> | 関数 | 各要素をチェックする条件 boolを返す必要がある |
Scene.my.any := (list, predicate)=>{
listLength := string.length(list);
if_then_else (listLength == 0 , {
false ;
}, {
if_then_else (predicate(list( 0 )), {
true ;
}, {
Scene.my.any(list( 1 .. (listLength - 1 )), predicate);
});
});
};
average
指定された数値リストの平均を返します。
- 使用法: Scene.my.average(<リスト>)
- 例: Scene.my.average([ 3 , 4 , 5 ])は4を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | フロートリスト | 操作対象のリスト |
ここで出てくる「フロートリスト」は、整数または浮動小数点数で構成されたリストと認識ください。
Scene.my.average := (list)=>{
sum := 0;
listLength := string.length(list);
for(listLength, (i)=>{
sum = sum + list(i);
});
sum / listLength;
};
contains
指定された要素がリスト内に存在する場合は true を返します。
- 使用法: Scene.my.contains(<リスト>, <要素>)
- 例: Scene.my.contains([ 3 , 4 , 5 ], 3 )は true を返す(リスト[ 3 , 4 , 5 ]には3が含まれているため)
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
<要素> | ブール型、浮動小数点型、文字列、または、それらのリスト | リストをチェックする要素 |
Scene.my.contains := (list, element)=>{
contains := false;
for(string.length(list), (i)=>{
if_then_else(list(i) == element, {
contains = true
}, {})
});
contains
};
filter
指定された条件を満たす、指定されたリストのすべての要素を含むリストを返します。
- 使用法: Scene.my.filter(<リスト>, <条件>)
- 例: Scene.my.filter(0..10, (n)=>{n > 5 })は[ 6 , 7 , 8 , 9 , 10 ] (0から10までの範囲内の5より大きい整数) を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
<条件> | 関数 | 各要素をチェックする条件 boolを返す必要がある |
Scene.my.filter := (list, predicate)=>{
newList := [];
for(string.length(list), (i)=>{
if_then_else(predicate(list(i)), {
newList = newList ++ list[i];
}, {});
});
newList;
};
fold
リストに対して関数(func)を実行し、リストの要素を結合して単一の値を返します。
- 使用方法: Scene.my.fold(<初期値>, <リスト>, <関数>)
- 例: Scene.my.fold( 0 , [ 3 , 4 , 5 ], (total, number)=>{total + number}) は12 (リスト内の数字の合計) を返す。
引数パラメータ | タイプ | 説明 |
---|---|---|
<初期値> | Any | 初期値 |
<リスト> | リスト | 操作対象のリスト |
<関数> | 関数 | 累積関数 |
Scene.my.fold := (initialValue, list, func)=>{
accumulator := initialValue;
for (string.length(list), (i)=>{
accumulator = func(accumulator, list(i))
});
accumulator
};
indexOf
指定されたリスト内の指定された要素の最初のインスタンスのインデックスを返します。
要素が見つからない場合は -1 を返します。
- 使用法: Scene.my.indexOf(<リスト>, <要素>)
- 例: Scene.my.indexOf([ “Hello” , “World” , “From” , “Thyme” ], “From” )は2を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
<要素> | Any | インデックスを検索する要素 |
Scene.my.indexOf := (list, element)=>{
index := -1;
for(string.length(list), (i)=>{
if_then_else(index == -1 && list(i) == element, {
index = i
}, {})
});
index
};
insertAtIndex
指定された要素をリストの指定されたインデックスに挿入し、新しいリストを返します。
- 使用方法: Scene.my.insertAtIndex(<リスト>, <インデックス>, <要素>)
- 例: Scene.my.insertAtIndex([ 3 , 4 , 5 ], 1 , 6 )は[ 3 , 6 , 4 , 5 ] を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
<インデックス> | 整数 | 新しい要素を挿入する場所 0の場合は先頭に挿入する |
<要素> | Any | リストに挿入する新しい要素 |
Scene.my.insertAtIndex := (list, index, element)=>{
list(0 .. (index - 1)) ++ [element] ++ list((index) .. (string.length(list) - 1))
};
map
指定されたリストの各要素に指定された関数を適用し、結果のリストを返します。
- 使用法: Scene.my.map(<リスト>, <関数>)
- 例: Scene.my.map( 0 .. 5 , (n)=>{n + 3 })は[ 3 , 4 , 5 , 6 , 7 , 8 ] (3から8までの整数) を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
<関数> | 関数 | 適用する関数 |
Scene.my.map := (list, func)=>{
newList := [];
for(string.length(list), (i)=>{
newList = newList ++ [func(list(i))];
});
newList;
};
max
指定された数値リストの最大値を返します。
- 使用法: Scene.my.max(<リスト>)
- 例: Scene.my.max([ 3 , 4 , 5 ])は5を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | フロートリスト | 操作対象のリスト |
Scene.my.max := (list)=>{
max := -inf;
for (string.length(list), (i)=>{
if_then_else (list(i) > max, {
max = list(i);
}, {})
});
max;
};
min
指定された数値リストの最小値を返します。
- 使用法: Scene.my.min(<リスト>)
- 例: Scene.my.min([ 3 , 4 , 5 ])は3を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | フロートリスト | 操作対象のリスト |
Scene.my.min := (list)=>{
min := +inf;
for (string.length(list), (i)=>{
if_then_else (list(i) < min, {
min = list(i);
})
});
min;
};
modifyAtIndex
リスト内の指定されたインデックスの要素を変更し、新しいリストを返します。
- 使用方法: Scene.my.modifyAtIndex(<リスト>, <インデックス>, <要素>)
- 例: Scene.my.modifyAtIndex([ 3 , 4 , 5 ], 1 , 6 )は[ 3 , 6 , 5 ] を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
<インデックス> | 整数 | 変更する要素を指すインデックス 0の場合は先頭の要素を変更する |
<要素> | Any | リストに追加する新しい要素 |
Scene.my.modifyAtIndex := (list, index, newElement)=>{
list( 0 .. (index - 1 )) ++ [newElement] ++ list((index + 1 ) .. (string.length(list) - 1 ))
};
quickSort
クイック ソート アルゴリズムを使用してリストをソートし、ソートされたリストを返します。
- 使用法: Scene.my.quickSort(<リスト>)
- 例: Scene.my.quickSort([ 3 , 5 , 4 ]) は[ 3 , 4 , 5 ] を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | フロートリスト | ソートするリスト |
Scene.my.quickSort = (arr)=>{
len := string.length(arr);
len <= 1 ? arr : {
average := 0;
for(len, (i)=>{
average = average + arr(i)
});
average = math.tofloat(average) / len;
smaller := [];
larger := [];
equal := [];
for(len, (i)=>{
arr(i) > average ? {
larger = larger ++ [arr(i)]
} : {};
arr(i) < average ? {
smaller = smaller ++ [arr(i)]
} : {};
arr(i) == average ? {
equal = equal ++ [arr(i)]
} : {}
});
Scene.my.quickSort(smaller) ++ equal ++ Scene.my.quickSort(larger)
}
};
removeAtIndex
指定されたインデックスの要素をリストから削除し、新しいリストを返します。
- 使用方法: Scene.my.removeAtIndex(<リスト>, <インデックス>)
- 例: Scene.my.removeAtIndex([ 3 , 4 , 5 ], 2 )は[ 3 , 4 ] を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
<インデックス> | 整数 | 削除する要素を指すインデックス 0の場合は先頭の要素を削除する |
Scene.my.removeAtIndex := (list, index)=>{
list( 0 .. (index - 1 )) ++ list((index + 1 ) .. (string.length(list) - 1 ))
};
removeFirstItem
リストから最初に一致する項目を削除し、新しいリストを返します。
- 使用方法: Scene.my.removeFirstItem(<リスト>, <要素>)
- 例: Scene.my.removeFirstItem([ 7 , 6 , 5 , 6 , 4 ], 6 )は[ 7 , 5 , 6 , 4 ] を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | 整数 or 浮動小数点数 or 文字列のリスト | 操作対象のリスト (数値のみ、または、文字列のみのリスト) |
<要素> | 整数 or 浮動小数点数 or 文字列 | 削除する要素 |
Scene.my.removeFirstItem := (list, item)=>{
output = [];
removedItem := false;
for(string.length(list), (i)=>{
! removedItem && list(i) == item ? {
removedItem = true
} : {
output = output ++ [list(i)]
}
});
output
};
removeItem
リストからアイテムに一致するすべての要素を削除し、新しいリストを返します。
整数 or 浮動小数点数 or 文字列のリストでのみ機能します。
リストには数値と文字列を混在させることはできません。
注意:リストに重複した項目がある場合、ターゲットになっていない場合でも、すべての重複は 1 つの項目にまとめられます。
- 使用方法: Scene.my.removeItem(<リスト>, <アイテム>)
- 例: Scene.my.removeItem([ 7 , 6 , 5 , 6 , 4 ], 6 )は[ 7 , 5 , 4 ] を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | 整数 or 浮動小数点数 or 文字列のリスト | 操作対象のリスト (数値のみ、または、文字列のみのリスト) |
<アイテム> | 整数 or 浮動小数点数 or 文字列 | 削除する要素 |
Scene.my.removeItem := (list, item)=>{
newList := set.merge([item], list);
newList(1 .. (string.length(newList) - 1))
};
removeItems
リスト#1から、リスト#2の項目に一致するすべての要素を削除し、新しいリストを返します。
整数 or 浮動小数点数 or 文字列のリストでのみ機能します。
リストには数値と文字列を混在させることはできません。
注意:リストに重複した項目がある場合、ターゲットになっていない場合でも、すべての重複は 1 つの項目にまとめられます。
- 使用方法: Scene.my.removeItems(<リスト#1>, <リスト#2>)
- 例: Scene.my.removeItems([ 7 , 6 , 5 , 6 , 4 ], [ 5 , 6 ])は[ 7 , 4 ] を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト#1> | 整数 or 浮動小数点数 or 文字列のリスト | 操作対象のリスト (数値のみ、または、文字列のみのリスト) |
<リスト#2> | 整数 or 浮動小数点数 or 文字列のリスト | 削除するリスト (数値のみ、または、文字列のみのリスト) |
Scene.my.removeItems := (list, items)=>{
newList := set.merge(items, list);
newList(string.length(items) .. (string.length(newList) - 1))
};
reverse
指定されたリストの順序を逆にしたリストを返します。
- 使用法: Scene.my.reverse(<リスト>)
- 例: Scene.my.reverse([ 3 , 4 , 5 ]) は[ 5 , 4 , 3 ] を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
Scene.my.reverse := (list)=>{
newList := [];
listLength := string.length(list);
for(listLength, (i)=>{
newList = newList ++ [list(listLength - 1 - i)];
});
newList;
};
shuffle
指定されたリストをシャッフルします。
- 使用方法: Scene.my.shuffle(<リスト>)
- 例: Scene.my.shuffle([ 0 , 1 , 2 ])は[ 1 , 0 , 2 ] を返す
引数パラメータ | タイプ | 説明 |
---|---|---|
<リスト> | リスト | 操作対象のリスト |
Scene.my.shuffle := (list)=>{
input := list;
output := [];
for(string.length(list), (i)=>{
index := math.toInt(rand.uniform01 * string.length(input));
output = output ++ [input(index)];
input = input(0 .. index - 1) ++ input(index + 1 .. string.length(input) - 1)
});
output
};
まとめ
本記事では、リスト操作などの使用頻度が高そうな関数に絞って解説しました。
有用そうな関数については都度追加していきます。
コメント