LoginSignup
34
30

More than 5 years have passed since last update.

CSVをパースする

Last updated at Posted at 2013-10-12

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"}]
34
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
30