みょんなものを書いたので、とりあえず。
ところどころ動作がおかしいけど、たぶん直します。
/*============================================================ * Enumerable 20090819 * c4se project - http://c4se.sakura.ne.jp * * project name: c4seJS * author: ne_Schirou - utakata.c4se@gmail.com * <c4seFCL 0.2> ============================================================*/ (function(){ /* * == usage * * Klass = function(){ * // codes * }; * Object.include(Klass.prototype, Enumerable.prototype); * Klass.prototype = { * forEach: function(f, o){ * // codes * } * }; * * * == cf. * * Array.prototype.forEach = function(f, o){ * var i = 0, * l = this.length; * for(; i<l; ++i){ * if(this[i] === undefined) continue; * f.call(o, this[i], i, this); * } * return this; * }; */ var _compare = function(l, r){ // default comparison function (by String charctor code) var i = 0, len = l.length; l = l.toString().split(''); r = l.toString().split(''); for(; i<len; ++i){ if(l[i].charCodeAt(0) < r[i].charCodeAt(0)) return -1; if(l[i].charCodeAt(0) > r[i].charCodeAt(0)) return 1; } return 0; }; Enumerable = function(){return this;}; Enumerable.prototype = { //_className: 'Enumerable', //forEach: forEach, every: function(f, o){ var tf = true; this.forEach(function(elm, i, _this){ if(elm === undefined) return null; if(!f.call(o, elm, i, _this)) tf = false; }, this); return tf; }, filter: function(f, o){ var a = new Array(); this.forEach(function(elm, i, _this){ if(elm === undefined) return null; if(f.call(o, elm, i, _this)) a.push(elm); }, this); return a; }, indexOf: function(v, n){ return this.toArray().indexOf(v, n); }, lastIndexOf: function(v, n){ return this.toArray().lastIndexOf(v, n); }, map: function(f, o){ a = new Array(); this.forEach(function(elm, i, _this){ if(elm === undefined) return null; a[i] = f.call(o, elm, i, _this); }, this); return a; }, reduce: function(f, v){ return this.toArray().reduce(f, v); }, reduceRight: function(f, v){ return this.toArray().reduceRight(f, v); }, some: function(f, o){ var tf = false; this.forEach(function(elm, i, _this){ if(f.call(o, elm, i, _this)) tf = true; }, this); return tf; }, sort: function(f){ f = f || _compare; return this.toArray().sort(f); }, toArray: function(){ var a = new Array(); this.forEach(function(elm){ a.push(elm); }, this); return a; }, // Extention like Ruby allQ: every, anyQ: some, car: function(){return this.toArray()[0];}, cdr: function(){return this.toArray().slice(1);}, collect: map, detect: function(f, o){ return this.filter(f, o)[0]; }, each: forEach, each_with_index: forEach, entries: toArray, find: detect, find_all: filter, grep: function(pattern, f, o){ //f = f || function(){return arguments[0];}; var a = new Array(); this.forEach(function(elm){ if(elm === undefined) return null; if(pattern === elm){ if(!f) a.push(elm); else a.push(f(elm)); } }); return a; }, includeQ: function(v){ var tf = false; this.forEach(function(elm){ if(elm === undefined) return null; if(elm == v) tf = true; }, this); return tf; }, inject: reduce, max: function(f){ f = f || _compare; var v, i = 0; this.forEach(function(elm){ if(i == 0){ v = elm; ++i; } else{ if(f(v, elm) < 0) v = elm; } }); return v; }, memberQ: includeQ, min: function(f){ f = f || _compare; var v, i = 0; this.forEach(function(elm){ if(i == 0){ v = elm; ++i; } else{ if(f(v, elm) > 0) v = elm; } }); return v; }, partition: function(f){ var at = new Array(), af = new Array(); this.forEach(function(elm, i, _this){ if(elm === undefined) return null; if(f.call(o, elm, i, _this)) at.push(elm); else af.push(elm); }, this); return [at, af]; }, reject: function(f){ var a = new Array(); this.forEach(function(elm, i, _this){ if(elm === undefined) return null; if(!f.call(o, elm, i, _this)) a.push(elm); }, this); return a; }, select: filter, sort_by: function(f){ return this.toArray().sort(function(l, r){ return f(l) - f(r); }); /*var a = this.map(f); return a.sort(function(l, r){return l - r;});*/ }, zip: function(/**/){ var f, arglen = arguments.length; if(arguments[arglen]._className == 'Function'){ f = arguments[arglen]; --arglen; } var a = new Array(); this.forEach(function(elm, i){ if(elm === undefined) return null; var b = [elm], j = 0; for(; j<arglen; ++j) b[j+1] = arguments[j][i]; a.push(b); }); if(!f) return a; var i = 0, v; while(v = a[i]) f(a[i++]); return null; } }; })();