それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Prototype.jsのRubyっぽい書式がうらやましい

Prototype.jsソースを読んでると、Arrayの拡張がうらやましい。EmEditorのマクロでも.net FrameworkからSystem.Collections.ArrayをActiveXオブジェクトで実体化してやると利用できそうだけれど。やっぱPrototypeっぽく書きたい

//EmEditorで開いてるファイルを処理がしたい
document.ReadAllLines().grep( "fo+" ).each(function(index,value){処理});

マクロ書いてみた。

1行ずつ読み込んで関数を適用するようにしてみた。7.00betaからGetLines(),GetLines(Y)が追加されたので早速利用している。今回はSelectAllしてTemp変数に読み込んだりしない。10000行のCSVファイルを順次処理するのが目標だからだ。

こういうオブジェクトを作っておく

1:a
2:b
3:c
4:d

この様なファイルを用意する。
このファイルへLinesオブジェクト適用するマクロを書く。

/*--
Utena.Lines定義は省略 
*/

//
//Utena.Lines()利用例
//
test_alert = function(line_txt,line_num){
  alert( line_num + "行目:" + line_txt );
  if( line_num >=10 ){
    alert("10行を超えたので、テスト実行を中止します");
    throw $stop_iteration;
  }
}

//各行にtest_alertを実行
lines.each( test_alert );//1行目:a,2行目:b,3行目:c,4行目:e...
//各行へGrep
array = lines.grep("c",function(txt,idx){ return idx+"行目;"+txt + "\n"; });
alert(array);//3行目:c


こういう事がしたいから、本体に取り込んでくれ。とEmEditor作者へ要望するのは、さすがに無茶だろうなぁ。

なので、ある程度は実装してみてる。

//省略した部分

///EmEditorのマクロ
///開いているドキュメントをEnumerationしたかった
Utena = {};//名前空間を指定
Utena.$stop_iteration = {val:-1,message:"stop"};

Utena.Enumerator = {
  each:function(iterator_function){
    try{
      //
      this._each(iterator_function);
    } catch (e) {
      if (e != Utena.$stop_iteration) throw e;
    }
        return this;
    },
  grep: function(pattern, iterator) {
    var results = [];
    this.each(function(value, index) {
      var stringValue = value.toString();
      if (stringValue.match(pattern)){
        results.push( (iterator || ( new Function("x","y","return x;") ))(value, index) );
      }
    })
    return results;
  }
};
Utena.Lines = function(){
  this.on_each_start = function(){ 
    Window.Redraw = false;//カーソル移動を隠蔽
    this.index = document.selection.GetActivePointY(eePosLogical);
    this.current_pos = {};
    this.current_pos.x = document.selection.GetActivePointX(eePosLogical);
    this.current_pos.y = document.selection.GetActivePointY(eePosLogical);
  },
  this.on_each_end  = function(){
      document.selection.SetActivePoint( eePosLogical, this.current_pos.x,this.current_pos.y,false );
      Window.Redraw = true;//カーソル移動を見せる

  };
  this._each = function(iterator_function){
    this.on_each_start();
    end_y = document.GetLines();//全部で何行あるか
    for( y=1;y<=end_y;y++ ){
      //iteratorを呼び出す
      iterator_function(  document.GetLine(y, false ), y );
      document.selection.SetActivePoint( eePosLogical, 1,y,false );//選択解除し1行下へ
    }
    this.on_each_end();
  };
};
Utena.Lines.prototype = Utena.Enumerator;
lines = new Utena.Lines();

今後コレを利用してこんなのを書くと思う。

//作りたい関数
lines.uniq();//同じ行を省略する
lines.findAll();//一覧をリンク書式で書き出し
lines.sort();//行をソート
lines.select();//見つけた行を取り出して別ファイルに書き出し
lines.reject();//条件に一致しない行を削除する
//prototype.jsから移植したいもの
//Hash全部
hash.toQuetyString();//特に欲しい

//CSVをArrayにするオブジェクトも欲しい
csv.toArray();//二次元配列になる
csv.toHashArray();//先頭行をIndexにしたオブジェクトの配列になる
csv.foramat();//CSVのTAB長を考慮して見やすくする

//ある程度は.netFrameworkのSystem.Collectionを利用すれば出来る