Enumerableクラス(2)

allメソッド

【抜粋】
  all: function(iterator) {
    var result = true;
    this.each(function(value, index) {
      result = result && !!(iterator || Prototype.K)(value, index);
      if (!result) throw $break;
    });
    return result;
  },

前述eachメソッドを、無名内部関数を引数にして呼び出しています。

無名内部関数は引数の関数(iterator)を、要素の値とインデックス*1を引数にして呼び出します。iteratorが無指定またはnullの場合は、前述Prototype.Kメソッド*2を呼び出しています。!!(***)は、***がnull(undefined)またはfalseであればfalse、それ以外であればtrueとなります*3。これとresultとの論理積をresultに格納し、resultがfalseならその時点で前述$breakエラーオブジェクトをthrowします*4

eachメソッド実行終了後、resultを返却します。

【例】
var array = ["zero", "one", null, "three"];
var ret = array.all(function(value, index){
  alert(index + ":" + value);
  return value;
});
//"0:zero","1:one", "2:null"まで表示される。 
alert(ret);//"false"が表示される。

配列の第3要素nullが"two"ならすべて表示され、最後もtrueになります。

throwされた$breakエラーオブジェクトはeachメソッドの二つのcatch節を両方通ります。一つ目では更にthrowされ、二つ目ではthrowされずに続行します。この動作に関しては前述eachメソッドの最後の【参考】で確認してみてください。(説明放棄とも言う><; すみません・・・。)

anyメソッド

【抜粋】
  any: function(iterator) {
    var result = true;
    this.each(function(value, index) {
      if (result = !!(iterator || Prototype.K)(value, index))
        throw $break;
    });
    return result;
  },

前述allメソッドと構造はほぼ一緒です。違いはiterator(またはPrototype.K)の結果が、null(undefined)またはfalseでない場合に$breakをthrowすることです。

【例】
var array = [null, false, "two", null];
var ret = array.any(function(value, index){
  alert(index + ":" + value);
  return value;
});
//"0:null","1:false", "2:two"まで表示される。 
alert(ret);//"true"が表示される。

配列の"two"もnullやfalseならすべて表示され、最後も"false"と表示されます。

以降、rejectメソッドまで基本構造は一緒です。それまでは簡単な説明と例のみ記述します。

collectメソッド

【抜粋】
  collect: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      results.push(iterator(value, index));
    });
    return results;
  },

iteratorの結果をresultにpushメソッド*5で追加していき、これを返却します。

【例】
var array = ["zero", "one", "two", "three"];
var ret = array.collect(function(value, index){
  return index + ":" + value;
});
alert(ret);
//retは配列。"0:zero,1:one,2:two,3:three"が表示される。

detectメソッド

【抜粋】
  detect: function (iterator) {
    var result;
    this.each(function(value, index) {
      if (iterator(value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  },

iteratorがtrueを返却した時点でbreak($breakをthrow)し、そのときの要素の値を返却します。

【例】
var array = ["zero", "one", "two", "three"];
var ret = array.detect(function(value, index){
  return (value.length == 3); //lengthが3の場合trueを返却
});
alert(ret);
//"one"が表示される。

findAllメソッド

【抜粋】
  findAll: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      if (iterator(value, index))
        results.push(value);
    });
    return results;
  },

iteratorがtrueを返却した場合、そのときの要素の値すべてを配列に格納して返却します。

【例】
var array = ["zero", "one", "two", "three"];
var ret = array.findAll(function(value, index){
  return (value.length == 3); //lengthが3の場合trueを返却
});
alert(ret);
//retは配列。"one,two"が表示される。

grepメソッド

【抜粋】
  grep: function(pattern, iterator) {
    var results = [];
    this.each(function(value, index) {
      var stringValue = value.toString();
      if (stringValue.match(pattern))
        results.push((iterator || Prototype.K)(value, index));
    })
    return results;
  },

第一引数patternは正規表現オブジェクトです。要素の値をtoStringで文字列化し*6、patternにマッチした場合のみ、iteratorで処理した結果を配列resultに格納して返却します。iteratorが指定なしの場合はPrototype.Kメソッドで値をそのまま扱います。

【例】
var array = ["zero", "one", "two", "three"];
var ret = array.grep(/.*o$/, //最後が"o"の文字列にマッチ
function(value, index){
  return value.toString().toUpperCase(); //大文字にして返却
});
alert(ret);
//retは配列。"ZERO,TWO"が表示される。

includeメソッド

【抜粋】
  include: function(object) {
    var found = false;
    this.each(function(value) {
      if (value == object) {
        found = true;
        throw $break;
      }
    });
    return found;
  },

引数は任意のオブジェクトobjectのみです。要素の値がobjectと同じオブジェクトだった場合、その時点でbreak($breakをthrow)します。見つかった場合はtrue、見つからなかった場合はfalseを返却します。

【例】
var object0 = new Object();
var object1 = new Array();
var object2 = new String();
var object3 = new RegExp();
var object4 = new Object();
var array = [object0, object1, object2, object3];
alert(array.include(object0)); //trueと表示される
alert(array.include(object4)); //falseと表示される

*1:処理された順番。必ずしも配列のインデックスではない。

*2:第一引数をそのまま返却するメソッド。

*3:!(***)の逆です

*4:ただ、論理積にする意味があまりない気がします。そのまま代入しても動作は同じような? なにかあるんでしょうか。

*5:Arrayクラス既存メソッド

*6:数値等、文字列以外の場合に対応するため