randomize

2016/05/29

Killzone KidのArmaスクリプト講座:Array(その3)

その2では配列の操作について見てきた。今回はもっと高度なもの、配列のコピーとかを見ていこう。

もし配列を_array2 = _array1といった感じに代入したとき、_array2は独自の配列ではなく、_array1を「参照」しているだけである。もし_array2を変更したなら、_array1も同時に変更される。他にも、_array1を関数の引数として使い、_array2を関数の中で変更しても同じように_array1に影響を及ぼす。
_array1 = [1,2,3];
_array2 = _array1;
_array2 set [2,0];
//_array1は[1,2,0]
a = {
    private ["_array2"];
    _array2 = _this;
    _array2 set [2,10];
};
_array1 call a;
//_array1は[1,2,10]になった
これを回避するには、空の配列から足したり引いたりして、その評価結果を代入するか、+演算子を使って配列を参照ではなくコピーする事もできる。これを覚えておいて、デバッグのときに痛い目を見ないようにしよう。
_array1 = [1,2,3];
_array2 = [] + _array1;
//_array2は[1,2,3]
_array2 set [2,0];
//_array1は[1,2,3]、_array2は[1,2,0]
_array2 = _array1 + [];
//_array2は[1,2,3]
_array2 set [2,10];
//_array1は[1,2,3]のまま、_array2は[1,2,10]
_array2 = _array1 - [];
//_array2は[1,2,3]
_array2 set [2,20];
//_array1は[1,2,3]のまま、_array2は[1,2,20]
_array2 = +_array1;
//_array2は[1,2,3]
_array2 set [2,30];
//_array1は[1,2,3]のまま、_array2は[1,2,30]
入れ子になっている配列を操作する時は、これまで通り階層を一つ一つ調べてお目当ての添字にたどり着いたところで処理する。
_array = [[1,2,3],[4,5,6],[7,8,[9,10]]];
((_array select 2) select 2) set [0,10];
//_arrayは[[1,2,3],[4,5,6],[7,8,[10,10]]]
一次元配列を反復する場合、forEachを使う。その1で見たcountのように、配列の値を一つずつ見ていく。特殊変数_xは現在反復中の値が代入され、特殊変数_forEachIndexは現在反復中の添字が代入される。
_array = ["John","Paul","George","Ringo","John","Paul","George","Ringo"];
_lastGeorgeIndex = -1;
{
    if (_x == "George") then {
        _lastGeorgeIndex = _forEachIndex;
    };  
} forEach _array;
//_lastGeorgeIndexは6
じゃあ次に面白いことをやっていこう。配列の中からランダムの値を取り出す外部関数、BIS_fnc_selectRandomとかはひとまず忘れて、賢くスクリプトの中でやっていこう。一行で同じことができる。(訳注:現在では命令selectRandomでより短くできます)
private ["_colours","_randomColour"];
_colours = ["green","yellow","purple","white"];
_randomColour = _colours select (floor (random (count _colours)));
//スマートだろ?
また、Armaには文字列の改変や正規表現、大文字小文字を区別する文字列比較などは存在しない(注:現在ではいくつか文字列関連の命令が追加されています)(例えば"hEllO" == "heLLO"trueになる。大文字小文字を区別したい場合switch/caseを使おう)。しかしながらtoArrayという命令が存在する。これは文字列を10進数のASCIIコードの数字の配列に変換する。用が済んだらtoStringで元に戻すことも出来る。ここに実用的な応用法を示してみよう。プレイヤーの名前をサニタイズして<と>を&lt;と&gt;に変換すればストラクチャードテキストに影響を及ぼさなくなる。
private ["_array","_temp","_sanitised"];
_array = toArray "<<<killzone_kid>>>";
_temp = [];
{
    switch _x do {
        case 60 : {
            _temp = _temp + toArray "&lt;";
        };
        case 62 : {
            _temp = _temp + toArray "&gt;";
        };
        default {
            _temp = _temp + [_x];
        };
    };
} forEach _array;
_sanitised = toString _temp;
//_sanitisedは&lt;&lt;&lt;Killzone_Kid&gt;&gt;&gt;
今回はこれで終わり、始めたときはその3まで来るなんて思ってなかったよ。何か役に立てたなら光栄だ。

Enjoy,
KK

その4へ

KK's blog – ArmA Scripting Tutorials: Arrays (Part 3) by Killzone Kid
Translated by POLPOX

0 件のコメント :

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。