- 2008年8月28日 19:06
- ActionScript 3.0
配列を扱っていると、条件に合うエレメントを絞り込みたいことがよくあります。
たとえば、クラスの生徒の名前を集約した配列があるとします。その中から、"ben"だけを抜いた配列を作りたい。
そんな時は、as3でArrayクラスに新しく実装されたfilterメソッドがお勧めです。
このパブリックメソッドは配列内の各エレメントについてテスト関数を実行し、指定された関数について true を返すすべてのエレメントを含む新しい配列を生成します。つまり、falseを返したエレメントはこの新しい配列には含まれません。
以下、サンプルコード
まず、対象となる配列を作成します。
var targetStrArr:Array,targetIntArr:Array
targetStrArr = new Array("tom", "ben", "emily");
次に、生成される配列の元になる配列を作成し、先ほど作成した対象となる配列に対してfilterを実行します。filterの第一引数にはコールバックファンクションを指定します。ここでは、benFilterというファンクションを指定しています。
//test1:ベン以外の名前を抽出
testArr = targetStrArr.filter(benFilter);
trace("test1:" + testArr);//test1:tom,emily
次に、フィルターとなるコールバックファンクションを記述します。このファンクションはbooleanを返し、引数にelement,index,arrayの三つを必要とします。この中に記述された条件式に基づいて、filterは新しい配列を作成します。以下の例では、elementがbenでなかったらtrueを返します。結果として、ben以外のストリングを持つ配列が生成されます。
function benFilter(element:String,index:int,arr:Array):Boolean{
return element != "ben"
}
しかし、これではben以外の名前をはぶき、なおかつ汎用性を持たせることはできません。そこで、いくつかのテクニックをご紹介します。
まず、その場の状況に応じてはぶく名前を変えたい場合です。filterにコールバックファンクションを引数として渡しているため、コールバックファンクション自体に引数を渡すことはできないように思われがちですが、実はできます。以下ではコールバックファンクションの返り値をFunctionにして、returnでファンクションが返るようにしています。返るファンクションは、前述と同じようにBooleanを返り値として持たせた無名関数です。この中に条件式を指定してあげることにより、引数を渡すことができます。nameFilterの引数で使用されている..restは、引数が複数存在する場合に備えて、引数を配列として保持するためのものです。引数には、rest[]でアクセスできます。このようにすることで、複数の要素でもフィルタリングが行えます。
testArr = targetStrArr.filter(nameFilter("tom","emily"));
function nameFilter(...rest):Function {
return function(element:String, index:int, arr:Array):Boolean {
var result:Boolean = true;
for(var _index:int in rest){
if(rest[_index] == element)result = false;
}
return result
}
}
最後のoddFilterでは、数値を集約した配列に対して、偶数のみを引き出す例です。
このように、Filterメソッドは様々な用途に対応できます。
以下に、今日ご紹介したすべてのサンプルコードを示します。
var targetStrArr:Array,targetIntArr:Array
targetStrArr = new Array("tom", "ben", "emily");
targetIntArr= new Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
var testArr:Array;
//test1:ベン以外の名前を抽出
testArr = targetStrArr.filter(benFilter);
trace("test1:" + testArr);//test1:tom,emily
//test2:対象の名前以外を抽出
testArr = targetStrArr.filter(nameFilter("tom","emily"));
trace("test2:" + testArr);//test2:ben
//test3:偶数だけを抽出
testArr = targetIntArr.filter(oddFilter);
trace("test3:" + testArr);//test3:2,4,6,8,10
function benFilter(element:String,index:int,arr:Array):Boolean{
return element != "ben"
}
function nameFilter(...rest):Function {
return function(element:String, index:int, arr:Array):Boolean {
var result:Boolean = true;
for(var _index:int in rest){
if(rest[_index] == element)result = false;
}
return result
}
}
function oddFilter(element:int, index:int, arr:Array):Boolean {
return !Boolean(element % 2)
}



