Posted at

javascriptでメソッドチェーンをしたい

More than 5 years have passed since last update.

javascriptはrubyやscalaと比べて下記の様な残念な点がある ( あくまで私個人の意見です )。


  • 便利なメソッドが少ない ( permutationsやuniqueなど )

  • メソッドチェーンを使えない

そこで、下記の様なメソッドを作ってみた。

// utility.js

/**
* prototypeオブジェクトにメソッドを追加
* @param name 追加するメソッド名
* @parame func 追加するメソッドの処理
*/

Function.prototype.method = function(name, func) {
if(!this.prototype[name]) {
this.prototype[name] = func;
return this;
}
};

/**
* 特定の要素のみ残した配列を作成
* @param condition 残す要素の条件
*/

Array.method('filter', function(condition) {
var ret = [];
for(var i = 0; i < this.length; ++i) {
if (condition(this[i])) {
ret.push(this[i]);
}
}
return ret;
});

/**
* 配列の各要素に指定した処理を実行
* @param func 配列の各要素に実行する処理
*/

Array.method('foreach', function(func) {
for(var i = 0; i < this.length; ++i) {
func(this[i]);
}
});

/**
* 配列の各要素に指定した処理を実行し新たな配列を作成
* @param func 配列の各要素に実行する処理
*/

Array.method('map', function(func) {
var i = 0;
var ret = [];
while(i < this.length) {
ret.push(func(i));
i += 1;
}
return ret;
});

/**
* 配列の各要素の合計値を計算
* @param initialValue 初期値
*/

Array.method('sum', function(initialValue) {
var sum = initialValue;
for(var i = 0; i < this.length; ++i) {
sum += this[i];
}
return sum;
});

/**
* 順列を計算
* @param src 順列を生成する配列 [1,2,3]など
* @param size 順列のサイズ
*/

function permutation(src, size) {
if(src.length < size) {
return;
}
var ret = [];
if(size === 1) {
for (var i = 0; i < src.length; ++i) {
ret[i] = [src[i]];
}
return ret;
}
for(var i = 0; i < src.length; ++i) {
var parts = src.slice(0);
parts.splice(i, 1)[0];
var s = permutation(parts, size - 1);
for (var j = 0; j < s.length; ++j) {
ret.push([src[i]].concat(s[j]).join(''));
}
}
return ret;
}

以下、使い方のサンプル。

permutation([1, 2, 3], 3).foreach(function(arg) { console.log(arg); }); // => 123 132 213 231 312 321

[1, 2, 3].map(function(arg) { return arg * 2; }).foreach(function(arg) { console.log(arg); }); // => 2 4 6

[1, ,2, 3].filter(function(arg) { return 2 <= arg; }).foreach(function(arg) { console.log(arg); }); // => 2, 3

console.log([1, 2, 3].sum(0)); // => 6

他にも追加したいメソッドはあるが、それはまた後日。