l'essentiel est invisible pour les yeux

Monday, November 13, 2006

[javascript] JavascriptでMap by Method

[ruby] RubyでMap by MethodをJavascriptに移植してみた。

SpiderMonkey限定になるのがとてもイタイのですが、IEでも同じような方法が試せないかあとで考える。(定義されていないメソッドを呼び出した際に呼び出すフックメソッドを定義するこの方法は何て名前がついてるんだろう?誰か教えてください。)


String.prototype.singularize = function() { // 手抜き実装
return this.replace(/s$/, '');
}
Array.prototype.map = function(lambda) {
var ret = [];
for(var i=0,l=this.length;i<l;i++) ret[i] = lambda(this[i]);
return ret;
}
Array.prototype.collect = Array.prototype.map;

Array.prototype.__noSuchMethod__ = function(name, args) {
if(match = name.match(/(map|collect)_([\w_]+)/)) {
iterator = match[1], methods = match[2].split('_and_');
return this[iterator](function(item) {
return methods.map(function(method){
return item[method];
});
});
} else {
return this.map(function(item){
return item[name.singularize()];
});
}
}

var data = [{name: 'Matz', lang: 'ja', loves: 'ruby'},
{name: 'DHH', lang: 'en', loves: 'ruby'},
{name: 'Takahashi', lang: 'ja', loves: 'ruby'},
{name: 'Moriq', lang: 'ja', loves: 'ruby'}];

console.log(data.names()); // => ["Matz","DHH","Takahashi","Moriq"]
console.log(data.map_name_and_lang()); // => [["Matz","ja"],["DHH","en"],["Takahashi","ja"],["Moriq","ja"]]
console.log(data.map_name_and_lang_and_loves()); // => [["Matz","ja","ruby"],["DHH","en","ruby"],["Takahashi","ja","ruby"],["Moriq","ja","ruby"]]


どう見てもString#singularizeが手抜き実装です。