経緯
元々xmlだったデータをJSONに変換。その際にkeyの重複に気付かず
JSONを参照する実装をしたとき、JSON上は存在するデータが該当しなかったため、今回のバグが発覚
状況
duplicate_data.json
{
"foo": "ふー",
"bar": "ばー",
"baz": "ばず",
"foo": "フー",
"bar": "バー",
"baz": "バズ"
}
"ふー"を取得したい。
parse.js
const data = require('./duplicate_data.json');
console.log(data);
読み込んで、表示してみる。
result
$ node parse.js
{ foo: 'フー', bar: 'バー', baz: 'バズ' }
Objectにparseされたときに、最後のkeyのvalueのみ格納されていたため、
目的のデータが取得できない。
対応策
Objectとしてparseすると、上記のように最後以外のvalueが消えるので、
ファイルデータを一行ずつ読み込んで、いい感じに加工することにしました
good_parse.js
const fs = require('fs');
const rs = fs.createReadStream('./duplicate_data.json');
const rl = require('readline');
const rli = rl.createInterface(rs, {});
let pairsAry = [];
let pairs = [];
let l = '';
// 読み込んだファイルを一行ずつ処理
rli.on('line', (line) => {
// 空白、改行を削除
l = line.trim();
// keyとvalueを含めた文字列を配列に分割
pairs = l.split(':');
// "や,など不要な部分を削除して配列を返す
pairs = pairs.map((val) => { return val.replace(/\"|\,/g, '').trim(); });
// keyとvalueが存在する配列だけ格納
if (pairs.length === 2) pairsAry.push(pairs);
});
let resultObj = {};
// 読み込みが終了したら実行
rli.on('close', () => {
let key, value;
pairsAry.forEach((val) => {
key = val[0];
value = val[1];
if (resultObj.hasOwnProperty(key)) {
// すでに同じkeyが存在する場合は、カンマ区切りでvalueを追加
resultObj[key] += ',' + value;
} else {
// keyが存在しない場合は、新規でvalueをセット
resultObj[key] = value;
}
});
// JSONファイルとして、書き出し
fs.writeFile('parsed_data.json', JSON.stringify(resultObj, null, 2));
});
parsed_data.json
{
"foo": "ふー,フー",
"bar": "ばー,バー",
"baz": "ばず,バズ"
}
めでたしめでたし
結論
絵文字をつかうと、記事がやわらかい雰囲気になって良い感じでした