2010年11月29日月曜日

Lisp の every と some 風の関数を JavaScript で

Common Lisp や Emacs Lisp 等では every や some という高階関数が提供されており、複数の値に対するテストを簡潔に記述することができる(述語関数/predicateの、リストへの適用)。

Lispの例

  (every #'evenp '(1 2 3)) => nil        ; 偶数でない要素があるため偽(nil)
  (some #'evenp '(1 2 3)) => t           ; 偶数の要素が少なくとも1個あるため真(t)

ここで、evenp は引数が偶数の場合に t を返す組み込み関数

JavaScriptの例

JavaScriptで同様のことを実現したいという場合は、次のような形になるはず。

// 関数定義
function every(p, arr){
  for (i = 0, n=arr.length; i < n; i++) {
    if(!p(arr[i])) return false;
  }
  return true;
}
function some(p, arr){
  for (i = 0, n=arr.length; i < n; i++) {
    if(p(arr[i])) return true;
  }
  return false;
}
function evenp(x){
  return (x%2==0) ? true : false;
}
// 実行
every(evenp, [1, 2, 3]);   // => false
some(evenp, [1, 2, 3]);    // => true

こんな感じ。

実は every, some が組み込まれているブラウザもある

念のため調べたところ、Firefox(Gecko 1.8b2 以降)にはこれらの関数が配列のメソッドとして実装されているとのこと。

everyの利用例(Mozilla Developer Center より転載)

function isBigEnough(element, index, array) {
  return (element >= 10);
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);
// passed は false

mozilla.orgのページにある「互換性」のコードを利用すれば、Firefox以外のブラウザでもeveryが利用できるようになる。

0 件のコメント:

コメントを投稿