Help us understand the problem. What is going on with this article?

重複したkeyを持つJSONデータをカンマ区切りvalueにまとめる

More than 3 years have passed since last update.

:pencil2: 経緯

元々xmlだったデータをJSONに変換。その際にkeyの重複に気付かず:innocent:

JSONを参照する実装をしたとき、JSON上は存在するデータが該当しなかったため、今回のバグが発覚 :imp:

:mag: 状況

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のみ格納されていたため、
目的のデータが取得できない。

:bulb: 対応策

Objectとしてparseすると、上記のように最後以外のvalueが消えるので、
ファイルデータを一行ずつ読み込んで、いい感じに加工することにしました:grin:

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": "ばず,バズ"
}

めでたしめでたし:clap:

:notebook_with_decorative_cover: 結論

絵文字をつかうと、記事がやわらかい雰囲気になって良い感じでした:kissing_smiling_eyes:

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした