CSVをパースする

  • 31
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

csvを配列に変換する関数

// ネイティブ版
function parseSV(str, delimiter){
  if(!delimiter) delimiter = ","
  return str.split('\n').reduce(function(table,row){
    if(!table) return;
    table.push(
      row.split(delimiter).map(function(d){ return d.trim() }) //余白削除
    );
    return table;
  }, []);
}

/* ネイティブ版はIE8以下では動かないので
 * underscore.jsを使う方が良いかも
 */
function _parseSV(str, delimiter){
  if(!delimiter) delimiter = ","
  return _.reduce(str.split('\n'), function(table,row){
    if(!table) return;
    table.push(
      _.map(row.split(delimiter), function(d){ return d.trim() }) 
    );
    return table;
  }, []);
}

使用

var csv = "name, age, job\n" +
    "清水,17,エンジニア\n" +
    "田中,34,デザイナー\n"+
    "佐藤, 21,マネージャー";

var csvArray = parseSV(csv);
console.log(csvArray);
-> [["name","age","job"],["清水","17","エンジニア"],["田中","34","デザイナー"],["佐藤","21","マネージャー"]]

デリミタを変更(tsv)

var tsv = "name address email\n" +
    "鈴木 東京都   suzuki@hoge.com\n" +
    "木村 群馬県   kimura@hoge.com";

var tsvArray = parseSV(tsv, "\t");
console.log(tsvArray);
->[["name","address","email"],["鈴木","東京都","suzuki@hoge.com"],["木村","群馬県","kimura@hoge.com"]]


オブジェクトに変換するwrapper と組み合わせる。

function toObject(array){
  var head = array.shift();
  var objArray = []; 
  for(var b=0; b < array.length; b++){
    var tmp = {};
    for(var i=0; i< head.length; i++){
      tmp[head[i]]=array[b][i];
    }
    objArray.push(tmp);
  }
  return objArray;
}

使用

var obj =  toObject(parseSV(csv));
console.log(obj);
->[{"name":"清水","age":"17","job":"エンジニア"},{"name":"田中","age":"34","job":"デザイナー"},{"name":"佐藤","age":"21","job":"マネージャー"}] 

composeを使う

var csv2obj = _.compose(toObject, parseSV);
var obj2 = csv2obj(csv);
console.log(obj2);
->[{"name":"清水","age":"17","job":"エンジニア"},{"name":"田中","age":"34","job":"デザイナー"},{"name":"佐藤","age":"21","job":"マネージャー"}] 

追記(tsv -> array -> obj)

underscore.jsで関数の部分適用を行う際に、束縛する引数の入れ替え等を行う方法がわからなかったので、mixinでflipメソッドを追加する。

_.mixin({
  flip:function(fn){
    return function() {
      var args = Array.prototype.slice.call(arguments);
      // flip arguments when called
      return fn.apply(this, args.reverse());
    };    
  }
});

引数(デリミタ)を部分適用

var tsv2array = _.partial(_.flip(parseSV), "\t"); //デミリタを部分適用する
var tsv2obj =  _.compose(toObject, tsv2array);
var obj3 = tsv2obj(tsv);
console.log(obj3);
->[{"name":"鈴木","address":"東京都","emailr":"suzuki@hoge.com"},{"name":"木村","address":"群馬県","emailr":"kimura@hoge.com"}]