情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

Node.jsでCSVデータやTSVデータを変換する

CSVデータ(やTSVデータ)を変換するストリームを作成するにはCSV for Node.jsパッケージのstream-transformモジュールを利用します。


streamTransform関数を呼び出します。

第1引数に変換関数を指定します。この関数の第1引数はレコードです。レコードはフィールド名が指定されている場合にはオブジェクトで表され、指定されていない場合には配列で表されます。この関数は返り値として変換後のレコードを返すようにします。

返り値としてストリームが得られます。

ストリームにCSVデータのレコードが読み込まれるとdataイベントが発生します。このイベントのイベントハンドラの第1引数は変換されたレコードです。


なお、ストリームの詳しい使い方に関しては下の記事を参照してください。

サンプルコード1

コマンドライン引数として与えられたCSVファイル(タブ区切りなので正確にはTSVファイルと言うべきかもしれません)を読み込み、変換を行い、標準出力に出力します。

stream-transform.js

var fs = require('fs');
var csvParse = require('csv-parse');
var streamTransform = require('stream-transform');

if (process.argv.length < 3) {
    console.error('lack argument.');
    process.exit(1);
}

var rs = null;
try {
    rs = fs.createReadStream(process.argv[2], 'utf-8');
    rs.on('error', function (err) {
        console.error(err);
        process.exit(1);
    });
}
catch (err) {
    console.error(err);
    process.exit(1);
}

var parser = csvParse({ delimiter: '\t' });
parser.on('error', function (err) {
    console.error(err);
    process.exit(1);
});

var transformer = streamTransform(function (data) {
    var after = [];
    for (var i = 0; i < data.length; i++) {
        if (data[i] != '') {
            after.push(data[i]);
        }
    }
    if (after.length != 4) {
        console.error('this is corrupted data.');
        return null;
    }
    else {
        after[0] = increment(after[0]);
        if (after[0] == null) {
            console.error('this is corrupted data.');
            return null;
        }
        after[1] = increment(after[1]);
        if (after[1] == null) {
            console.error('this is corrupted data.');
            return null;
        }
        return after;
    }
});
transformer.on('data', function (data) {
    console.log(data);
});
transformer.on('error', function (err) {
    console.error(err);
    process.exit(1);
});

rs.pipe(parser).pipe(transformer);

function increment(level) {
    if (level == `*`) {
        return level;
    }
    else {
        var n = parseInt(level, 10);
        if (n == NaN) {
            return null;
        }
        else {
            return (n + 1).toString(10);
        }
    }
}

使用パッケージ

実行結果

現在のフォルダには下のような内容のenglish.csvという名称のTSVファイルが存在しています。

3       1       reading                 測定値
2       1       style                   ~と呼ぶ、様式
3       2       due                     ~することになっている、期限が来て、正当な
3       3       ankle                   足首
4       3       discipline              訓練、規律、分野、学科
4       3       extraordinary           異常な
3       3       joint                   接合(部)、関節、いかがわしい場所、共同の
4       3       virtue                  美徳、効力
5       4       bundle                  ~を束ねる、束
4       4       deceive                 ~をだます
5       4       reproduce               ~を複製する
6       4       rip                     ~を引き裂く
4       4       substitute              ~を代わりに用いる、~を置換する、代用品、代用の
6       5       cashier                 現金出納係、レジ係
4       5       envy                    ~をうらやむ、うらやましさ
6       5       mouthful                口いっぱい、正しい言葉
6       5       reap                    ~を収穫する、~を得る
5       5       refresh                 ~の元気を回復させる
6       5       refreshment             元気回復、飲食物、軽食
6       6       deceit                  詐欺

english.csvを第1引数としてコードを実行すると結果は下のようになりました。正しく変換されていることが分かります。

C:\work\node>node stream-transform.js english.csv
[ '4', '2', 'reading', '測定値' ]
[ '3', '2', 'style', '~と呼ぶ、様式' ]
[ '4', '3', 'due', '~することになっている、期限が来て、正当な' ]
[ '4', '4', 'ankle', '足首' ]
[ '5', '4', 'discipline', '訓練、規律、分野、学科' ]
[ '5', '4', 'extraordinary', '異常な' ]
[ '4', '4', 'joint', '接合(部)、関節、いかがわしい場所、共同の' ]
[ '5', '4', 'virtue', '美徳、効力' ]
[ '6', '5', 'bundle', '~を束ねる、束' ]
[ '5', '5', 'deceive', '~をだます' ]
[ '6', '5', 'reproduce', '~を複製する' ]
[ '7', '5', 'rip', '~を引き裂く' ]
[ '5', '5', 'substitute', '~を代わりに用いる、~を置換する、代用品、代用の' ]
[ '7', '6', 'cashier', '現金出納係、レジ係' ]
[ '5', '6', 'envy', '~をうらやむ、うらやましさ' ]
[ '7', '6', 'mouthful', '口いっぱい、正しい言葉' ]
[ '7', '6', 'reap', '~を収穫する、~を得る' ]
[ '6', '6', 'refresh', '~の元気を回復させる' ]
[ '7', '6', 'refreshment', '元気回復、飲食物、軽食' ]
[ '7', '7', 'deceit', '詐欺' ]

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js