Edited at

CSVをパースする

More than 5 years have passed since last update.


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"}]