理由
私はこれまで JavaScript 言語を使用したことがありましたが、結局のところ、それは JavaScript プロジェクトどころか、バックエンドと連携するために書かれたいくつかの散在する「コード スニペット」のためでした。先月この会社に着任したばかりで、私たちのチームは以前のバージョンを改善し、それを超えるという非常に明確な目的を持って、アーキテクチャと実装をゼロから開始しました。これは実際の JavaScript の「プロジェクト」です。もちろん、私たちのチームはサーバー側の責任を負いません。私が本格的に JavaScript でプログラミングを本格的に始めたのもこの頃です。学校では形式手法に興味があり、JavaScript は関数型言語なので、JavaScript を使ってより関数的なものを表現したいと考えていました。
いくつかの関数
これらのメソッドはすべて、JavaScript 1.6 配列の新しいメソッドです。非常に典型的な機能であり、もちろん実用性も非常に高いです。次の関数の定義は JavaScript からのものではありません。
filter: セット Xs (X は型を表し、s はセットを表します) と述語を受け入れます。この述語は X から bool へのマッピング (関数) です。次に、このセットをフィルターし、述語が true である要素のセットを返します。以下は簡単な実装です:
関数フィルター(arr,callback ){
var i,out=[];
for(i=0;i
if(callback(arr[i]))
out.push (arr[i]);
}
return out
}
簡単なテストを追加します:
var arr = [1,2,3,4,5,6,7,8, 9,10];
var Even = function(item){
if(typeof item !== "number") return
return !(item & 1); 🎜>var filtered = filter(arr,even);
console.log(filtered);
結果:
2,4,6,8,10
マップ:セット Xs、関数 f を受け入れ、f を使用して Xs セット内の各要素を順番にマップし、セット f x1、f x2、f x3... f xn を返します。実装は次のとおりです。
function map( arr,callback){
var i,l= arr && arr.length || 0,out = new Array(l);
for(i=0;iout[ i]=callback(arr [i]);
return out
}
コードをコピーします。
コードは次のとおりです。
11,12,13,14,15,16,17,18,19,20
さらに、JavaScript 1.6 で登場した forEach、every、some という 3 つの関数があります。 。しかし、使っているうちに、まだ強力な機能が欠けていると感じます。それが、折り畳み機能です。 「map-reduce」ということわざがあるように、「reduce」のないマップがあるのは残念ではないでしょうか。この「減らす」について考えてみましょう。
Reduce の実装
上記の Reduce は、実際にはfold 関数 (fold) です。 X のセットと二項演算子 f を受け入れます。次に、セット内の隣接する 2 つの要素ごとに f が挿入されます。たとえば、fold plus [1,2,3,4] は 1 2 3 4 を意味します。より正確には、「開始要素」は通常、f の先頭の 2 番目のパラメーターとして必要です。たとえば、fold plus [1,2,3,4] は (1 (2 (3 (4 0))) を意味します。実装は次のとおりです:
Copy code
コードは次のとおりです。 x=b,i= 0;
else x=arr[0],i=1; for(;i
x=callback(arr[i],x) );
return x;
コードをコピーします
コードは次のとおりです:
var arr = [1,2,3,4,5,6,7,8,9,10];
var plus = function(a,b) ){
戻り値
};
var フォールドプラス = 折り畳み(arr,plus,0);
結果:
55
この関数は ECMAScript 5 ではreduce と呼ばれますが、関数式では通常、fold と呼ばれます。これは非常に鮮やかな名前です。
まとめ
実は、JavaScript 言語にはループ文があるため、上記の関数関数を実装する際の書き方は機能的ではありません。ループ文がない場合はどうなるでしょうか?次の探索に任せてください。