prototype.js を使う

作成日:2007-11-18
最終更新日:

prototype.js は、Ajax の進展に伴って注目されている JavaScript ライブラリである。 私が面白いと思ったのは、関数型言語 Haskell などで使われる畳み込み関数 foldl や foldr に似た機能を、 prototype.js で実装していることを知ったからだ。

foldl に関しては、実際の記法は Haskell より Ruby に似ている。

[3, 1, 4].inject(0, function(acc, item) { return acc + item });

このコードの意味は、次のようになる。

  1. 最初の値 acc が 0 で初期化される。
  2. 次に acc と 配列の0番目の要素(=3)が足され、新たな acc(=3) になる。
  3. 次に acc と 配列の1番目の要素(=1)が足され、新たな acc(=4) になる。
  4. 次に acc と 配列の2番目の要素(=4)が足され、新たな acc(=8) になる。
  5. 最終結果のaccがこの式の値となる

この説明はいかさまで、本来関数型言語では acc の書き換えは起こらない。 しかし、手続き型言語で習ってきた性ゆえ、以上のような理解が一番わたしにはぴったりくる。

メソッドを追加してしまう

これに味をしめて、Array クラスにメソッドを追加してしまおう。 これらは、Array の配列をベクトルや行列とみなしたときの操作である

// 要素の和
Array.prototype.sum = function() {
	return this.inject(0.0, function(memo, v){
	return memo + parseFloat(v)})
}

// 要素の平均
Array.prototype.average = function() {
	return this.sum() / this.length
}

// ベクトルどうしの内積
Array.prototype.innerProduct = function(v) {
	return (this.zip(v, function(x){return x[0]*x[1]})).sum()
}

// 行列の転置
Array.prototype.transpose = function() {
	var u = new Array(this[0].length)
	for (var i = 0; i < u.length; i++) {
		u[i] = new Array(this.length)
		for (var j = 0; j < u[i].length; j++) {
			u[i][j] = a[j][i]
		}
	}
	return u
}

これらの準備は、二元配置表の分散分析のためであった。 本当は、行列の転置は Haskell や OCaml の例のようにかっこよく作りたかったが、諦めた。

まりんきょ学問所JavaScript 手習い > prototype.js を使う


MARUYAMA Satosi