JavaScript/Prototype/Enumerable

1月 1, 2003 · Posted in JavaScript, Prototype · Comment 

Enumerableオブジェクトとはなにか。

JavaScriptには複数の繰り返し書式があります。
たいていの場合は配列やリスト形式のデータに対しての
繰り返し処理に利用します。

たとえば、

while(条件式) {
//処理
}

や、

for (初期処理; 継続条件; ループごとの処理) {
//処理
}

さらには、

do{
//処理
}while(条件式);

などがあります。

用途により使い分けができて便利なのですが、配列やリスト形式のデータに対する繰り返し処理を想定した場合、すこし冗長な感じがします。

そこで、prototype.jsにはEnumerableオブジェクトが用意されており、リストに対するシンプルでわかりやすい繰り返し処理を利用することができます。

基本の書式

prototype.jsでは、生成したArrayクラスがEnumerableクラスのメソッドを利用できるように拡張されています。
これにより開発者は、普段どおり配列を生成するだけで、拡張メソッドを利用することができます。

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var list = new Array("hello", "bye"); // (1)
list.each(function(element){ // (2)
alert(element); // (3)
});
// –>
</script>

実行結果

hello
bye

コード説明

Enumerableによるループ処理は、プログラム言語Rubyで利用できる繰り返し書式ににています。

-コード(1)
–配列を生成しています。一般的なJavaScriptのコードです。
-コード(2)
–生成した配列はprototype.jsにより拡張されているため、Enumerableクラスのメソッドが利用できます。
–単純な繰り返し処理をおこなうeachメソッドを呼び出しています。
-コード(3)
–コード(2)の繰り返しにより、各要素が順番に渡されます。
–繰り返し処理が実行されるたびに、配列の各要素をelementという名前で受け取っています。
–スコープ内でelement要素に対する処理を記述します。

上記の書式を覚えるだけでも配列に対する繰り返し処理を簡潔に記述できるようになります。
さらに便利に利用するために、以下にEnumerableクラスの各メソッドの利用方法を記述します。

each:繰り返し処理

配列オブジェクトに対して単純な繰り返し処理を実行します。

書式

each(iterator)

パラメータ

iterator: 関数オブジェクト。function(value, index)

<script type="text/javascript" src="prototype.js"></script>

<input id="input1" value="abcd">
<input id="input2" value="defg">

<script type="text/javascript">
<!–
var list = $("input1", "input2");
list.each(function(element, idx){
alert(idx + ":" + element.value);
});

// –>
</script>

結果

0:abcd
1:defg

all:すべての要素が条件を満たしているかチェックする。

allメソッドを利用すると、配列のすべての要素が指定した条件を満たしているか調べることができます。
すべての条件を満たしているときはtrueが、ひとつでも満たしていない要素が存在する場合はfalseが返ります。

書式

all([iterator])

パラメータ

iterator: 関数オブジェクト。function(value, index) 省略可能。

<script type="text/javascript" src="prototype.js"></script>

<input class="data" value="100">
<input class="data" value="99">
<input class="data" value="101">
<input class="data" value="102">

<script type="text/javascript">
<!–
var list = document.getElementsByClassName("data");
var result = list.all(function(element){
var data = element.value;
return data > 99; // (1)
});
alert(result);

// –>
</script>

結果

false

データの中に99があるため、(1)部分の条件を満たしていません。結果はfalseとなります。
(1)部分を「data > 98」とした場合、結果はtrueとなります。

any:要素に指定した条件を満たしているものが存在するか調べる

anyメソッドを利用して、配列の中に指定した条件を満たしているものがひとつでも存在しているか調べることができます。

書式

any([iterator])

パラメータ

iterator: 関数オブジェクト。function(value, index) 省略可能。

<script type="text/javascript" src="prototype.js"></script>

<input class="data" value="100">
<input class="data" value="99">
<input class="data" value="98">
<input class="data" value="97">

<script type="text/javascript">
<!–
var list = document.getElementsByClassName("data");
var result = list.any(function(element){
var data = element.value;
return data > 99; // (1)
});
alert(result);

// –>
</script>

結果

true

(1)の条件を満たすものがひとつでもあれば、結果はtrueとなります。
例では、要素中に99を超えるデータが存在しているため、結果はtrueとなります。

collect:すべての要素に指定した処理を実行し、結果を配列として取得する

collectメソッドを利用して、配列のすべての要素に対して指定した処理を実行し、その返却値を配列として取得することができます。

書式

collect(iterator)

パラメータ

iterator: 関数オブジェクト。function(value, index)

<script type="text/javascript" src="prototype.js"></script>

<input class="data" value="100">
<input class="data" value="1500">
<input class="data" value="10000">
<input class="data" value="2000">

<script type="text/javascript">
<!–
var list = document.getElementsByClassName("data");
var result = list.collect(function(element){
var data = element.value;
return data * 1.05; // (1)
});
alert(result);

// –>
</script>

結果

105,1575,10500,2100

(1)の処理の部分で渡されたデータに1.05を掛け、税込み金額を算出しています。

detect:指定した条件を満たした最初の要素を取得する。

detectメソッドを利用すると、配列中で指定した条件を満たした最初の要素を取得することができます。
指定した条件に一致する要素がひとつもない場合は、nullが返ります。

書式

detect(iterator)

パラメータ

iterator: 関数オブジェクト。function(value, index)

<script type="text/javascript" src="prototype.js"></script>

<input class="data" id="1" value="100">
<input class="data" id="2" value="1500">
<input class="data" id="3" value="10000">
<input class="data" id="4" value="100">

<script type="text/javascript">
<!–
var list = document.getElementsByClassName("data");
var result = list.detect(function(element){
var data = element.value;
return data == "100"; // (1)
});
alert(result.id);

// –>
</script>

結果

1

例中のinput要素のうち、(1)の条件を満たすものはid=1とid=4の2つです。
detectメソッドでは条件に一致した最初の要素が取得できるので、id=1の要素が取得されました。

entries():集合のすべての要素を配列にする

集合のすべての要素を配列に変換します。

書式

entries()

パラメータ

なし

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var range = $R(0, 5);
var result = range.toArray();
alert(result);
// –>
</script>

結果

0,1,2,3,4,5

find:指定した条件を満たした最初の要素を取得する

detectと同一

findAll:指定した条件を満たしたすべての要素を取得する

配列中のすべての要素より、指定した条件を満たすものを抽出します。

書式

findAll(iterator)

パラメータ

iterator: 関数オブジェクト。function(value, index)

<script type="text/javascript" src="prototype.js"></script>

<input class="data" id="1" value="100">
<input class="data" id="2" value="1500">
<input class="data" id="3" value="10000">
<input class="data" id="4" value="100">

<script type="text/javascript">
<!–
var list = document.getElementsByClassName("data");
var result = list.findAll(function(element){
var data = element.value;
return data == "100"; // (1)
});
alert(result.length);

// –>
</script>

結果

2

(1)の条件を満たす要素が抽出されるため、結果は2件となります。

grep:正規表現に一致する要素をすべて取得する

指定した正規表現にマッチした要素をすべて取得します。

書式

grep(pattern [,iterator])

パラメータ

pattern: 正規表現のパターン文字列
iterator: 関数オブジェクト。function(value, index)

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var data = new Array("apple", "grape", "pineapple", "egg");
var result = data.grep("pple");
alert(result);
// –>
</script>

結果

apple,pineapple

include:指定したオブジェクトが集合内に存在するか調べる

指定したオブジェクトが集合の中に存在しているか調べる場合は、includeメソッドを利用します。
見つかった場合trueが、見つからなかった場合はfalseが返ります。

書式

include(object)

パラメータ

object: 集合内から検索するオブジェクト

<script type="text/javascript" src="prototype.js"></script>

<input class="data" id="1" value="100">
<input class="data" id="2" value="1500">
<input class="data" id="3" value="10000">
<input class="data" id="4" value="100">

<script type="text/javascript">
<!–
var list = document.getElementsByClassName("data");
var result = list.include($("1"));
alert(result);
// –>
</script>

結果

true

//**inGroupOf:集合のグループ化
//inGroupOf関数を利用すると、集合を指定した数ごとにグループ化(分割)することができます。
//[1,2,3,4,5,6]→[1,2,3][4,5,6]
//[1,2,3,4,5]→[1,2,3][4,5,*]
//のようなことができます。
//
//書式
// inGroupsOf(number [,fillWith])
//
//パラメータ
// number: 分割時の各グループの要素数。
// fillWith: 項目が空いた場合に設定する文字。省略した場合null。
//
//例
// <script type="text/javascript" src="prototype.js"></script>
// <script type="text/javascript">
// <!–
// var data = new Array("apple", "grape", "pineapple", "egg");
// var result = data.inGroupOf(3, "*");
// alert(result);
// // –>
// </script>
//
//結果
// [apple,grape,pineapple],[egg,*,*]
//
//

inject:値を変化させながら繰り返し処理を実行する

書式

inject(initial, iterator)

パラメータ

initial: 繰り返し処理に与える初期値
iterator: 関数オブジェクト。function(data, value, index)

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var range = $R(1, 10);
var result = range.inject(0, function(value, idx){
return value + idx; // (1)
});
alert(result);
// –>
</script>

結果

55

初期値0に対して、(1)の部分で集合の値を加算しています。
結果的に、1から10を加算した結果55を得ることができます。

invoke:集合の各要素に対して実行するメソッドを指定する。

invokeコマンドに関数名を渡すことで、集合のすべての要素に対して指定したメソッドが実行されます。
可変長引数をとるようになっており、引数をいくつでも渡すことができます。

書式

invoke(methodName [,arg1] [,arg2] … [,argn])

パラメータ

methodName: 実行するメソッド名。
[,arg1] [,arg2] … [,argn]: 実行するメソッドに渡すパラメータ。いくつでも指定可能。

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–

var array = new Array("<javascript>", "&prototype&");
var invokeArray= array.invoke("escapeHTML");
alert(invokeArray);

// –>
</script>

実行結果

&lt;javascript&gt, &amp;prototype&amp;

すべての要素に対してescapeHTML関数を実行しています。

map:すべての要素に指定した処理を実行し、結果を配列として取得する

collectと同一

max:集合の要素から最大値を取得する。

maxメソッドを利用して、集合内の最大値を取得する場合ことができます。

書式

max([iterator])

パラメータ

iterator: 関数オブジェクト。function(value, index)。省略可能。指定した場合、返却値が一番大きかった要素が返却されます。

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var list = new Array(100, 20, 7, -200, 5);
var max = list.max();
alert(max);
// –>
</script>

結果

100

例2

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var list = new Array(100, 20, 7, -200, 5);
var max = list.max(function(data){
return Math.abs(data);
});
alert(max);
// –>
</script>

例2結果

200

例2では、各要素にMath.abs関数(値の絶対値を求める関数)が実行され、結果が一番大きかったものが返却されました。

member:指定したオブジェクトが集合内に存在するか調べる

includeと同一

min:集合の要素から最小値を取得する。

minメソッドを利用して、集合内の最小値を取得する場合ことができます。

書式

mix([iterator])

パラメータ

iterator: 関数オブジェクト。function(value, index)。省略可能。指定した場合、返却値が一番小さかった要素が返却されます。

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var list = new Array(100, 20, 7, -200, 5);
var min = list.min();
alert(min);
// –>
</script>

結果

-200

partition:集合をtrueを返すものとそれ以外に分割する。

集合を、trueを返すものとそれ以外のものに分割した配列を取得します。

書式

partition([iterator])

パラメータ

iterator: 関数オブジェクト。function(value, index)。省略可能。

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var list = new Array(100, 20, 7, -200, 5);
var result = list.partition(function(data){
return data > -1; // (1)
});
alert(result[0]);
alert(result[1]);
// –>
</script>

結果

100,20,7,5
-200

処理(1)の部分の判定がtrueとなったデータの一覧が返却値の0番目の要素に設定され、それ以外の要素の配列が1番目の要素に設定された
二つの配列を含んだ配列が取得できました。

pluck:指定したプロパティの配列を取得する

pluck
http://eow.alc.co.jp/pluck/

【自動】
引っ張る
【他動】
〜をむしる、むしり取る、引き抜く、グイッと引っ張る

集合の各要素より、指定した名前のプロパティ値を取得して配列として返します。

書式

pluck(propertyName)

パラメータ

propertyName: 要素から抽出するプロパティの名前

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var list = new Array("100", "20", "7", "-200", "5");
var result = list.pluck("length");
alert(result);
// –>
</script>

実行結果

3,2,1,4,1

各要素の文字列長(文字列オブジェクトのlengthプロパティ)を取得しました。

reject:指定した条件を満たさなかったすべての要素を取得する

reject関数を利用すると、集合内の要素のうち、指定した条件を満たさなかった要素を配列として取得することができます。

書式

reject(iterator)

パラメータ

iterator: 関数オブジェクト。function(value, index)

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var list = new Array("100", "20", "7", "-200", "5");
var result = list.reject(function(data, idx){
return data.length > 1; //(1)
});
alert(result);
// –>
</script>

結果

7,5

処理(1)で指定した「文字列長が2以上」という条件を満たさなかった要素が抽出されました。

select:指定した条件を満たしたすべての要素を取得する

findAllと同一

sortBy:要素の並べ替えを行う

書式

sortBy(iterator)

パラメータ

iterator: 関数オブジェクト。function(value, index)

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var list = new Array("100", "-20", "7", "-200", "5");
var result = list.sortBy(function(data, idx){
return Math.abs(data); //(1)
});
alert(result);
// –>
</script>

実行結果

5,7,-20,100,-200

処理(1)の部分でデータを絶対値にして返却しているため、すべての要素が絶対値の昇順に並べ替えられました。

toArray():集合のすべての要素を配列にする

entries()と同一

zip:配列のマージ処理を行う

zip関数を利用して集合のマージ処理を行うことができます。

書式
 zip(collection1[, collection2 [, ... collectionN [,transform]]])

パラメータ

collection: 可変パラメータ。マージ対象の配列を指定する。
transform: 関数オブジェクト。function(value, index)

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
<!–
var list = new Array("1", "2", "3");
var result = list.zip(["4", "5"], ["6", "7"], function(data){
return data.reverse();
});
alert(result[0]);
alert(result[1]);
alert(result[2]);
// –>
</script>

実行結果

6,4,1
7,5,2
,,3

最初に以下の3つの配列がある。

[1,2,3]
[4,5]
[6,7]

zipメソッドを実行した結果、以下のような配列ができあがる

[[1,4,6],[2,5,7],[3,,]]

この各配列に指定した処理(reverse)を実行しているので結果は

6,4,1
7,5,2
,,3

となる。