079.【Id】タブ区切りテキストのテーブルをJSON形式(っぽい配列)にする
タブ区切りの文字列をJSON形式(っぽい配列)にする関数です。
事前にタブ区切りのtxtデータを読み込んでから実行することを想定しています。
生成した配列を使ってInDesignで自動組版したり、JSONファイルを作成して他のアプリケーションに渡したりするために作りました。
指定した行をヘッダーとして扱い、それより上の行はスキップします。
引数
書名: 令和3年度 論文集 ページ番号 氏名 学年 学籍番号 写真ファイル名 14 田中一郎 1 1111 1111.psd 16 田中二郎 2 2222 2222.psd 18 田中三郎 3 3333 3333.psd 32 田中四郎 4 4444 4444.psd
戻り値
[ { ページ番号: '14', 氏名: '田中一郎', 学年: '1', 学籍番号: '1111', 写真ファイル名: '1111.psd' }, { ページ番号: '16', 氏名: '田中二郎', 学年: '2', 学籍番号: '2222', 写真ファイル名: '2222.psd' }, { ページ番号: '18', 氏名: '田中三郎', 学年: '3', 学籍番号: '3333', 写真ファイル名: '3333.psd' }, { ページ番号: '32', 氏名: '田中四郎', 学年: '4', 学籍番号: '4444', 写真ファイル名: '4444.psd' }, ];
コード
メモ
例外処理
throw
文は、ユーザー定義の例外を発生させます。現在の関数の実行は停止し(throw
の後の文は実行されません)、
コールスタック内の最初のcatch
ブロックに制御を移します。呼び出し元の関数にcatch
ブロックが存在しない場合は、プログラムが終了します。
→関数内でエラーを投げると以降の処理がなされないので、ファイルを開いたあとclose()
する前にエラーを投げないようにする。
→関数でエラーを投げる場合は、必ずtry/catch/finally
とともに呼び出す。
CSV
CSVにも対応したかったのだけど、結構めんどうそう。
フィールド内にカンマやダブルコーテーションが含まれていた場合を考えると、単純にsplit(',')
ではうまくいかない。
デフォルト引数
function txt2json(str, separator, header = 0) {...
のように記述することで、関数の定義時に引数にデフォルト値を設定することができる。
該当の引数が渡されなかった場合や undefined
が渡された場合にこの値が用いられる。
この仕様はES2015(ES6)からサポートされている。
つまりES3準拠であるExtendScriptでは使えない。
代わりに今回は var header = header || 0;
という書き方をした。
あとになって、こういった場合の理想の書き方はどないなもんか気になり、デフォルト引数を使用した関数をTypeScriptで書いてコンパイルしてみた。
//default_arg_test.ts function default_arg_test (a = 0) { const res = a; return res; } const output = default_arg_test() $.writeln(output); //0
これが
//default_arg_test.js "use strict"; function default_arg_test(a) { if (a === void 0) { a = 0; } var res = a; return res; } var output = default_arg_test(); $.writeln(output); //0
こうなる。
if (a === void 0) { a = 0; }
が今回知りたかったところ。
void演算子は必ずundefined
を返す演算子。
なぜa === 'undefined'
で判定するよりよろしいかというと、undefined
が書き換え可能であるから(少なくともES3においては)。
var a $.writeln(a) //undefined $.writeln(a === undefined) //true $.writeln(a === void 0) //true var undefined = "test" //書き換えると… $.writeln(a === undefined) //false!! $.writeln(a === void 0) //true
(ES5.1以降ではグローバルなundefined
は書き換え不可となっているようです)
今後はa === void 0
かtypeof a === 'undefined'
を使おうと思います。
その他
- includeはエイリアスは読みこんでくれない。
- デスクトップはパスで指定せずとも
Folder.desktop
でOK。 - 引数の名前を
char
としようとしたら「予約語だからだめ」と怒られた。予約語なんですね。 - Excelデータをタブ区切りテキストとして保存すると、カンマが入っている場合にダブルコーテーションで囲まれる。カンマ区切りじゃないのに。
- xlsxデータは
File.read()
できない。exclude()
で開くことはできる。
参考
- JavaScriptでCSVデータ(項目行あり)をJSON形式に変換する | Try Lifelog
- CSV文字列をJSONオブジェクトに変換 | JavaScript逆引き | Webサイト制作支援 | ShanaBrian Website
- [JavaScript] CSVテキストを配列に分割する。「","」「"改行"」対応 - Qiita
- 【JavaScript】エラー処理 完全ガイド
- delimiter / separator / divider の違い - codic ブログ 変数名の参考にした。
- 「テーブル」「レコード」「カラム」「フィールド」とは? 変数名の参考にした。
追記
ExtendScriptでのjsonファイルの読み込みについて、後日ひとつ学びがあったので追記。
「ExtendScriptのオブジェクトとしてそのまま読めるようなjsonファイルであれば、
var hoge= #include "hoge.json"
とするだけで、変数hogeにhoge.jsonをパースしたオブジェクトが入ります。」
便利!
さらに追記
dataはMapにした方が安全かもしれない。
(2022/05/09)