Enumerable は Prototype フレームワークの基礎であり、Prototype では、他のオブジェクトが Enumerable のメソッドを混合して使用されるため、これらのオブジェクトには Array、Hash、ObjectRange が含まれます。 、DOM と AJAX に関連するいくつかのオブジェクト。
Enumerable は、列挙 (値のコレクションとして機能するオブジェクト) のための便利なメソッドの大きなセットを提供します。これは、
Enumerable をモジュールと呼びます。 : 独立した使用を目的としたものではなく、mixin を目的とした一貫したメソッドのセット。
プロトタイプでは、かなりの数のオブジェクトがすでに混合列挙可能です。は Array と Hash ですが、ObjectRange やさまざまな DOM または AJAX 関連のオブジェクトなど、あまり目立たない場所でも見つかります。
上記の文は、おそらく Enumerable がプロトタイプの基礎であることを意味します。 Prototype の他のオブジェクトは Enumerable のメソッドを混合するため、これらのオブジェクトには Array、Hash、ObjectRange、および DOM 関連のオブジェクトが含まれます。 。
個人的には、Enumerable は C の抽象クラスの概念に相当すると理解しています。他のクラスはこのクラスを継承して Enumerable の抽象メソッド "_each" を実装したり、他のメソッドをオーバーライドしたりできますが、Enumerable 自体をインスタンス化することはできません。 、そのサブクラスのみをインスタンス化できます。
Enumerable を使用して独自のクラスを作成する方法を見てみましょう:
コードをコピーします コードは次のとおりです:
var YourObject = Class.create ();
Object.extend(YourObject.prototype, Enumerable); Object.extend(YourObject.prototype, {
initialize: function() {
// 任意のコンストラクター引数を使用
// 構築コード
},
_each: function(iterator) {
// 毎ターン反復子を呼び出す反復コード
},
// Enumerable オーバーライドを含む他のメソッドもここにあります
});
最も重要なことは _each メソッドを実装することであることがわかります。initialize メソッドはコンストラクターと同等です。外部パラメータが必要ない場合は、省略しても問題ありません。以下に乱数配列を生成するクラスを作成しました。これは非常に単純ですが、多くの不完全な点があります。
コードをコピーします。 コードは次のとおりです。次のように:
//RandomArray クラスを作成します
var RandomArray = Class.create();
//mixin Enumerable
Object.extend(RandomArray.prototype, Enumerable);
/ / _each と必要なメソッドを実装します。
Object.extend(RandomArray.prototype, {
初期化: function(min,max,count) {
this.min=min;
this. max= max;
this.count=count;
this._createRandomArray();
_each: function(iterator) var インデックス =this.count; 🎜> _createRandomArray:function(){
var インデックス = 0;
while(index
} 、
には次のものが含まれます。 function(number){
return this._numbers.indexOf(number)!=-1 ;
}
});
var obj = new RandomArray(
//alert(obj.size()); .entries());
Enumerable のソース コードを見て、各メソッドを詳しく学習します。
コードをコピー
コードは次のとおりです:
var $break = { };
var Enumerable = (function() {
//各データを走査
function each(iterator, context) {
varインデックス = 0;
try {
this._each(function(value) {
iterator.call(context, value,index );
} catch (e) {
if (e != $break) throw e;
}
return this;
}
//データを N 個のグループに分割し、各グループには数値が割り当てられます。最後のグループは数値より小さい可能性があります
function eachSlice(number, iterator, context) {
var index = -number, スライス = [], array = this.toArray();
if (number
) 1) 配列を返します。
while ((index =number)
}
//すべてのデータが特定の条件を満たすかどうかをテストします。
function all(iterator, context) {
iterator = iterator || = true;
this.each(function(value,index) {
result = result && !!iterator.call(context, value,index);
if (!result) throw $break;
});
return result;
}
// データが特定の条件を満たすかどうかを確認します。
function any(iterator, context) {
iterator = iterator || Prototype.K;
var result = false;
this.each(function(value,index) {
if (result = !!iterator.call(context, value,index) ))
throw $break;
});
return result;
}
//すべてのデータに対して任意の操作を実行し、結果を返すことができます
関数collect (iterator, context) {
iterator = iterator || Prototype.K;
var results = [];
this.each(function(value,index) {
results.push(context, value) ,index));
});
return results;
// 特定の条件を満たす最初のデータを検索し、それを返します。 find メソッド
関数 detect(イテレータ, コンテキスト) {
var result;
this.each(関数(値, インデックス) {
if (イテレータ.call(コンテキスト, 値, インデックス) ) {
result = value;
throw $break;
}
});
return result; 特定の条件を満たすすべての項目を検索しますデータを取得し、結果を返します。
function findAll(iterator, context) {
var results = [];
this.each(function(value,index) {
if (iterator.call(context , value,index))
results.push(value);
});
return results;
//フィルター条件に従ってすべてのデータをフィルターします。フィルター条件を満たすデータと結果を返す
//フィルターは文字列または正規表現です
function grep(filter, iterator, context) {
iterator = iterator || var results = [];
if (Object.isString(filter))
filter = new RegExp(RegExp.escape(filter));
this.each(function(value,index)) {
if (filter.match(value))
results.push(iterator.call(context, value,index))
});
結果を返します。 >
//特定のデータが含まれているかどうかを確認します
function include(object) {
if (Object.isFunction(this.indexOf))
if (this.indexOf(object) != - 1 ) true を返します;
var found = false;
this.each(function(value) {
if (value == object) {
found = true;
throw $ Break;
}
});
return found;
// eachSlice メソッドと同様、最後のグループの要素の数が number より小さい場合、 fillWith パラメータを使用します。 Fill
function inGroupsOf(number, fillWith) {
fillWith = Object.isUnknown(fillWith) ? null : fillWith>return this.eachSlice(number, function(slice) {
while(slice. length
) slide.push(fillWith);
return slide;
}
//累積を達成するために、すべてのデータに対して操作を継続的に実行します。または累算 乗算およびその他の演算
function inject(memo, iterator, context) {
this.each(function(value,index) {
memo = iterator.call(context, memo, value, index) ;
});
return memo;
//すべてのデータに対してメソッドを実行する
function invoke(method) {
var args = $A(arguments) ) .slice(1);
return this.map(function(value) {
return value[method].apply(value, args);
}
//data
function max(iterator, context) {
iterator = iterator ||
var result;
this.each(value) , インデックス ) {
値 = iterator.call(context, value,index);
if (結果 == null || 値 >= 結果)
結果 = 値
});
return result;
}
//データの最小値を見つける
関数 min(iterator, context) {
iterator = iterator || >var result ;
this.each(function(value,index) {
value = iterator.call(context, value,index);
if (result == null || value < result)
result = value;
});
return result;
}
//最初のグループは特定の条件を満たすデータです。 2 番目のグループ 条件を満たさないデータの場合
functionpartition(iterator, context) {
iterator = iterator ||
var trues = [], falses = []; 🎜>this.each(function(value,index) {
(iterator.call(context, value,index) ?
trues : falses).push(value);
}); trues, falses];
}
//すべてのデータのプロパティ値を取得し、結果を返します
function pluck(property) {
var results = []; >this .each(function(value) {
results.push(value[property]);
});
return results;
}
//結果を検索特定の条件データを満たさない
function raise(iterator, context) {
var results = [];
this.each(function(value,index) {
if (!iterator. call(context, value ,index))
results.push(value);
});
return results;
// 特定の条件に従ってすべてのデータを並べ替えます。条件
function sortBy(iterator, context) {
return this.map(function(value,index) {
return {
value: value,
criteria: iterator.call(context, value, インデックス)
};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? - 1 : a > ; 1 : 0;
}).pluck('value')
//データの配列表現を返します
関数 {
return this.map();
}
//基本的に 2 つのデータセットをまとめて特定の操作を実行します
function zip() {
var iterator = Prototype.K , args = $A(arguments);
if (Object.isFunction(args.last()))
iterator = args.pop();
var collections = [this].concat (args ).map($A);
return this.map(function(value,index) {
return iterator(collections.pluck(index));
}); 🎜>
function size() {
return this.toArray().length;
}
//Enumerable オブジェクトを表す文字列表現を返します
function Inspection() {
return '#
}
return {
each: each,
eachSlice: eachSlice 、
all: すべて、
every: すべて、
any: 任意、
some: 任意、
collect: 収集、
map: 収集、
detect: 検出、
findAll: findAll、
select: findAll、
filter: findAll、
grep: grep、
include: include、
member: include、
inGroupsOf: inGroupsOf、
inject: 注入、
invoke: 呼び出し、
max: 最大、
min: 分、
partition: パーティション、
pluck: 摘み取る、
reject: 拒否、
sortBy: sortBy、
toArray: toArray、
entries: toArray、
zip: zip、
size: サイズ、
inspect: 検査、
find: 検出
} ;
})();
Enumerable が提供するメソッドを学習しましょう:
all
any
detect
各
エントリ
find
findAll
grep
inGroupsOf
include
inject
invoke
map
max
member
min
partition
pluck
reject
select
size
sortBy
toArray
zip
all メソッド:
すべての要素は、直接または提供された反復子による計算を通じて、ブール値的に true と等価です。
基本的に各メソッドを呼び出して、各データが反復子の条件を満たしているかどうか、およびそれらの 1 つが反復子の条件を満たしていないかどうかを確認します。イテレータ条件で、$break が例外をスローすると、この例外は各メソッドでキャッチされます。ここでの「!!」の使用法に注意してください。これにより、特定のオブジェクトが対応する bool 値に変換されます:
!!{} true
!![] true
!! 'False
!!' 文字列 'true
例を見てみましょう:
🎜> コードをコピーします
コードは次のとおりです:
[].all()// -> true (空の配列には false と同等の要素がありません) )
// -> true ([1..5] のすべての値は true と同等です) [0, 1, 2].all()
// -> false (ループサイクルが 1 つだけの場合: 0 は false と同等)
[9, 10, 15].all(function (n) { return n > = 10; })
// -> false (反復子は 9 で false を返します)
$H({ 名前: 'ジョン'、年齢: 29 , oops: false }).all (function(pair) { return parse.value; })
// -> false (oops/false ペアは false の値を生成します)
any メソッド:
は all メソッドと似ているため、詳細については説明しません。
コードは次のとおりです:
[].any()
// -> false (空の配列には true と同等の要素がありません)
$R(0, 2).any( )
// -> true (2 番目のループ サイクルでは、1 は true に相当します)
[2, 4, 6, 8, 10].any(function(n) { return 0 == n % 3; })
// -> true (反復子は 6 で true を返します。配列には 1 の 3 の倍数があります)
$H({ opt1: null, opt2 : false, opt3: '', opt4: 'pfew!' }).any(function(pair) { return pain.value; })
// -> true (opt4/'pfew!' のおかげで)
collect/map (collect メソッドのエイリアス) メソッド:
反復子を適用した結果を返します。
これは、シーケンス用のスイスアーミーナイフのようなものです。
このメソッドは「スイス」と呼ばれます。 Army Knife" "このメソッドは、基本的にデータに対してあらゆる操作を実行できます。map メソッドの実装は非常に簡単です。文が重要です。各データに対してイテレータ呼び出しを行い、結果を配列に格納して返されます。例を見てください。
コードをコピーします。 > コードは次のとおりです:
['Hitch', "Hiker's", 'Guide', 'To', 'The', 'Galaxy'].collect(function(s) { return s.charAt(0).toUpperCase(); }) .join('')
// -> 'HHGTTG'
$R(1,5).collect(n) { return n * n; })
// -> [1, 4, 9, 16, 25]
ヘルプ ドキュメントの最後の数行に注目してください。 🎜>
まず、メソッド呼び出しのシナリオです。すべての要素で同じメソッドを、場合によっては引数を使用して呼び出し、その結果の値を使用します。これは、
2 つ目で簡単に実現できます。プロパティフェッチのシナリオ: すべての要素で同じプロパティをフェッチし、それらを使用する必要があります。これは、pluck を使用すると簡単です:
に一致する最初のデータを見つけます。実際、このメソッドは find のエイリアスなので、 detect と find の呼び出しは同じです:
コードをコピーします。
// わずかに圧縮された最適な正確な素数検出方法。function isPrime(n) { if (2 > n) return
if (0 == n % 2) return (2 == n);for (var Index = 3; n / Index > Index; Index = 2)
if (0 == n % Index) return false;
return true;
// isPrime
$R(10,15).find(isPrime) // -> 11
['こんにちは' 、'世界'、'これ'、'です'、'いい'].find(function(s) { return s.length <= 3; })
// ->
各メソッド:
<span style="font-family:新宋体">$ continue<strong></strong></span>
は、速度を優先して Prototype 1.5 以降のリリースでは使用できなくなります。 .
例を見てください:
コードをコピーします コードは次のとおりです:<span style="font-family:新宋体">$continue</span>
['1', '2', '3'].each(function(s) { アラート (s); });
// アラート -> '0: hello' then '1: world'
// ここで... var result = []; $R(1,10).each(function(n) {
if (0) == n % 2) throw $ continue; (n > 6) throw $break;result.push(n); 1、3、5]
eachSlice メソッド:
多くの単純なメソッド以下のメソッドは例として示されています。これ以上説明しません。アルゴリズムについては基本的に同じです。
コードをコピーします
var 学生 = [ { 名前: 'サニー', 年齢: 20 }, { 名前: 'オードリー', 年齢: 21 }, { 名前: 'マット', 年齢: 20 }, { 名前: 'エロディ'、年齢: 26 }、{ 名前: 'ウィル'、年齢: 21 }、{ 名前: 'デビッド'、年齢: 23 }、{ 名前: 'ジュリアン'、年齢: 22 }、{ 名前: 'トーマス' , 年齢: 21 }, { 名前: 'セルピル', 年齢: 22 } ];
students.eachSlice(4, function(toon) { return toon.pluck('name'); })
// -> [ ['サニー'、'オードリー'、'マット'、'エロディ']、
// ['ウィル'、'デヴィッド'、'ジュリアン'、'トーマス']、
// ['Serpil'] ]
//以下の最初のメソッドは Array オブジェクトによって提供されます
students.eachSlice(2).first()
// -> name : 'Sunny', age: 20 }, { name: 'Audrey', age: 21 }]
entries メソッドは toArray メソッドであり、map メソッドはtoArray メソッド、マップ このメソッドは、collect メソッドと同等です:
コードをコピー コードは次のとおりです:
$R(1, 5).toArray() // - > [1, 2, 3, 4, 5]
find/findAll (select メソッドのエイリアス) メソッド:
コードをコピー コードは次のとおりです:
//find メソッド
[ 'hello', 'world', 'this', 'is' , 'nice'].find(function(s) { return s.length // -> 'is'
//findAll メソッド
$R(1, 10).findAll(function(n) { return 0 == n % 2; })
// -> [2, 4, 6, 8, 10] [ 'hello', 'world', 'this ', 'is', 'nice'].findAll (function(s) { return s.length >= 5; })
// -> ['hello', 'world']
grep メソッド:
このメソッドで注意する必要があるのは、パラメーター フィルターを関数内で正規表現に統合する必要があり、その後正規表現の match メソッドが呼び出されるということです。判断する
コードをコピー コードは次のとおりです:
// どこかに文字が繰り返されている文字列をすべて取得します
['こんにちは'、'世界'、'これ'、'です'、'クール'].grep (/(.)1/)
// -> ['こんにちは', 'クール']
/ / 0 または 5 で終わるすべての数値を取得
$R(1,30).grep (/[05]$/)
// -> [5, 10, 15, 20, 25, 30]
// これらから 1 を引いたもの
$R(1,30).grep (/[05]$/, function(n) { return n - 1; })
// -> [ 4, 9, 14, 19, 24, 29]
// どこかで文字が繰り返されているすべての文字列を取得します
['hello', 'world', 'this', 'is', 'cool']。 grep(/(.)1/)
// -> ['hello' , 'cool']
// 0 または 5 で終わるすべての数字を取得します
$R(1,30)。 grep(/[05]$/)
// -> [5, 10 , 15, 20, 25, 30]
// これらから 1 を引いたもの
$R(1,30)。 grep(/[05]$/, function(n) { return n - 1; })
// -> [4, 9, 14, 19, 24, 29]
inGroupsOf メソッド:
コードをコピー コードは次のとおりです:
var students = [ { name: 'Sunny',年齢: 20 }, { 名前: 'オードリー', 年齢: 21 }, { 名前: 'マット', 年齢: 20 }, { 名前: 'エロディ', 年齢: 26 }, { 名前: 'ウィル', 年齢: 21 }, { 名前: 'デビッド'、年齢: 23 }、{ 名前: 'ジュリアン'、年齢: 22 }、{ 名前: 'トーマス'、年齢: 21 }、{ 名前: 'セルピル'、年齢: 22 } ];
//pluck メソッドはオブジェクトの特定の属性を取得するもので、ここでは name 属性が取得されます。
students.pluck('name').inGroupsOf(4)
// -> [ ['サニー', 'オードリー', 'マット', 'エロディ'],
// ['ウィル', 'デヴィッド', 'ジュリアン', 'トーマス'],
// ['セルピル', null, null, null] ]
include/member(include メソッド エイリアス) メソッド。ここでは、まずオブジェクトにindexOf メソッドがあるかどうかを確認し、存在する場合は呼び出します。このメソッドを直接:
コードをコピー コードは次のとおりです:
$R(1,15).include(10)
// -> true
['hello', 'world'].include('HELLO')
/ / -> false
[1, 2, '3', '4' , '5'].include(3)
// -> true (== 実際の型を無視)
注入メソッド:
コードをコピー コードは次のとおりです:
$R(1,10).inject(0, function(acc, n) { return acc n; })
// -> 55 (1 ~ 10 の合計)
$R(2,5).inject(1, function(acc, n) { return acc * n; })
// -> 120 (factorial 5)
['hello', 'world' , 'this', 'is', 'nice'].inject([], function(array, value, Index) {
if (0 == Index % 2) array.push(value);
配列を返す;
})
// -> ['hello', 'this', 'nice']
メソッドを呼び出す:
コードをコピー コードは次のとおりです:
['hello', 'world', 'cool!'].invoke('toUpperCase')
// ['HELLO', 'WORLD', 'COOL!']
['hello', 'world', 'cool!'].invoke('substring', 0, 3)
// [ 'hel', 'wor', 'coo']
最大/最小メソッド:
コードをコピーコードは次のとおりです:
$R(1,10).max() // -> 10
['hello', 'world', 'gizmo'].max( )
// -> 'world'
function person(name, age) { this.name = name; this.age = age; }
var john = new person('John', 20) );
var マーク = 新しい人 ('マーク', 35);
var デイジー = 新しい人 ('デイジー', 22);
[ジョン, マーク, デイジー].max(人) ) { return person.age })
// -> 35
パーティションメソッド:
コードは次のとおりです。
['hello', null, 42, false, true, , 17].partition()
// -> '、42、true、17]、[null、false、未定義]]
$R(1, 10).partition(function(n) { return 0 == n % 2; })
// -> [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]
['hello', null, 42, false, true, , 17].partition( )
// -> [['hello', 42, true, 17], [null, false, 未定義]]
$R(1, 10).partition(function(n) { return 0 == n % 2; })
// -> [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]
pluck メソッド:
コードをコピー コードは次のとおりです:
['hello', 'world', 'this' , 'is', 'nice'].pluck( 'length')
// -> [5, 5, 4, 3, 4]
拒否メソッド:
コードをコピー コードは次のとおりです:
$R(1, 10).reject(function(n) { return 0 == n % 2; })
// -> [1, 3, 5, 7, 9]
[ 'hello', 'world', 'this', 'is', ' nice'].reject(function(s) { return s.length >= 5; })
// -> ['this', 'is', 'nice']
$R(1 , 10).reject(function(n) { return 0 == n % 2; })
// -> [1, 3, 5, 7, 9]
[ 'hello', 'world ', 'this', 'is', 'nice'].reject(function(s) { return s.length >= 5; })
// -> ['this', 'is', 'nice']
size メソッドは省略されています。
sortBy メソッド:
このメソッドは、最初にマップ メソッドを通じてオブジェクト配列を返し、次に配列の sort メソッドを呼び出し、最後にオブジェクトの value 属性を取り出します
コードをコピーします コードは次のとおりです:
['hello', 'world', 'this', 'is', 'nice'].sortBy( function(s) { return s.length ; })
// -> 'is', 'this', 'nice', 'hello', 'world']
['hello', 'world' ', 'this', 'is' , 'cool'].sortBy(function(s) {
var md = s.match(/[aeiouy]/g);
return null == md ? 0 : md.length;
} )
// -> [ 'world', 'this', 'is', 'hello', 'cool'] (母音数で並べ替え)
zip メソッド :
コードをコピー コードは次のとおりです:
var firstNames = ['Justin', 'Mislav', 'Tobie', 'Christophe'];
var lastNames = ['Palmer', 'Marohnić', 'Langel', 'Porteneuve'] ;
firstNames.zip(lastNames)
// -> [['ジャスティン', 'パーマー'], ['ミスラフ', 'マローニッチ'], ['トビー', 'ランゲル'] 'Christophe', 'Porteneuve']]
//この例から、パラメーター a が配列であり、2 つの配列内の対応する項目を表すことがわかります。
firstNames.zip(lastNames, function(a) { return a.join(' '); })
// -> ['Justin Palmer', 'Mislav Marohnić', 'Tobie Langel', 'Christophe Porteneuve']
// この例では、次のことができます。
var city = ['Memphis', 'Zagreb', 'Montreal', 'Paris'];
firstNames.zip(lastNames, citys, function(p) { return p) で複数の配列を渡すことができることを確認してください。 [0] ' ' p[1] ', ' p[2] })
// -> ['ジャスティン・パーマー、メンフィス'、'ミスラフ・マローニッチ、ザグレブ'、'トビー・ランゲル、モントリオール', ' Christophe Porteneuve、パリ']
firstNames.zip($R(1, 100), function(a) { return a.reverse().join('. '); })
// -> [「1. ジャスティン」、「2. ミスラフ」、「4. クリストフ」]