c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

Enumerable.js

みょんなものを書いたので、とりあえず。
ところどころ動作がおかしいけど、たぶん直します。

/*============================================================
 * 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;
  }
};

})();