質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

5回答

5309閲覧

JavaScript Object,JSONデータの同名キーの値を読み取る方法

gucha

総合スコア55

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

2クリップ

投稿2020/04/07 10:18

編集2020/04/07 21:27

コード内にあるオブジェクト形式のデータに同名のkeyが使われていた場合について。
JavaScript側からこれらのキーを独自のものとして値を読み取る方法はあるのでしょうか?

Javascript

1{ 2"key1": "value1", 3"key2": "value2", 4"key1": "value3" 5}

コード(テキスト)としてはデータが残っているのですが、量が多くて人力でキーを修正していくのは困難です。
プレーンテキストを正規表現などを利用してオブジェクトに作り直す方法を思いつきましたが、他にも良い方法があれば教えて頂きたいです。
整形する方法はJavaScript以外でも大丈夫です。既存のツールなどがあればそちらを利用します。

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2020/04/07 10:28

シングルクォートはJSONでは使えません。 また、値として持てるものも決められていて、value1 という識別子は使えないと思います。 以上より、そのファイルはJSONではなく、JavaScriptなのではないかな、と感じました。
退会済みユーザー

退会済みユーザー

2020/04/07 10:44

そもそもユニークであると定義されてる
gucha

2020/04/07 21:28

サンプルコードを修正しました。ご指摘ありがとうございます。
guest

回答5

0

ベストアンサー

それはJSONとしておかしいので、
まともな方法で値を取り出す事は不可能です。

データクレンジングを行い妥当なJSONに整形しなければ読み書きできません

では早速やっていきましょう。
基本的には改行コードを全て潰して1行の文字列に潰してしまうのが楽でしょう。
※ただし、""等の文字列に囲まれたエリアで改行やカンマ等の文字を扱っている場合は高度なエスケープ処理が出来るので、1文字ずつ取得していくやり方が必要になります。

js

1const json = `{ 2'key1': value1, 3'key2': value2, 4'key1': value3 5}`; 6 7console.log( 8 json.replace(/\r?\n/g, "") 9); 10// "{'key1': value1,'key2': value2,'key1': value3}" 11 12console.log( 13 json 14 .replace(/\r?\n/g, "") 15 .trim() // trimで文字列前後のホワイトスペースを削除して 16 .slice(1, -1) // 先頭と末尾の文字を捨てて{}の中身を抽出 17 .split(",") // カンマで切って配列化 18); 19// ["'key1': value1", "'key2': value2", "'key1': value3"]

ここで配列になるので、今度はfor..of文で加工していきましょう。

js

1const json = `{ 2'key1': value1, 3'key2': value2, 4'key1': value3 5}`; 6 7const data = json 8 .replace(/\r?\n/g, "") 9 .trim() 10 .slice(1, -1) 11 .split(","); 12 13const result = []; 14for (const datum of data) { 15 // datum = "'key1': value1" 16 const [key, val] = datum.split(":").map(it => it.trim()); 17 result.push({key, val}); 18} 19console.log(result);

json

1[ 2 { 3 "key": "'key1'", 4 "val": "value1" 5 }, 6 { 7 "key": "'key2'", 8 "val": "value2" 9 }, 10 { 11 "key": "'key1'", 12 "val": "value3" 13 } 14]

key値が"'key1'"みたいになっていますが、
先頭の文字を取り出してチェックしてシングルクォートだとわかるなら
最初と最後の文字を切り飛ばすようにしていけばすすめると思います。

投稿2020/04/07 10:42

miyabi-sun

総合スコア21203

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gucha

2020/04/07 21:50

目的が達成できる方法でなおかつ一番早い回答だったのでこちらをベストアンサーに選びました。 回答して頂いた皆様ありがとうございました。
guest

0

Symbolにできるならワンチャンあるかも

js

1const o = { 2[Symbol('key1')]: "value1", 3[Symbol('key2')]: "value2", 4[Symbol('key1')]: "value3" 5}; 6 7Object.getOwnPropertySymbols(o).length //3

投稿2020/04/07 10:42

Lhankor_Mhy

総合スコア36960

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gucha

2020/04/07 21:54

Symbolのこのような使い方は知らなかったのでとても勉強になりました。 今回私は使用しませんでしたが、こちらのやり方の方が目的に合うケースもあると思いました。
guest

0

こんにちは

この回答では、パイプでつなぐことを意図した、以下の2つのコマンドライン用スクリプトを作ります。

(1) data2xml: 標準入力から、ご質問に提示されている形式の、以下のようなテキストを受け取り、等価な情報を持つXMLを作って標準出力に表示する。

plain

1{ 2'key1': value1, 3'key2': value2, 4'key1': value3 5}

(2) xml2json: 標準入力からXMLを受け取って、JSONに変換にして標準出力に表示する。

ご質問に

整形する方法はJavaScript以外でも大丈夫です。

とありましたので、Python で書きました。

$ python -V

Python 3.7.4
$ cat data.txt

plain

1{ 2'key1': value1, 3'key2': value2, 4'key1': value3 5}

$ cat data2xml.py

python3

1import sys 2import re 3 4for line in sys.stdin: 5 s = line.strip() 6 7 if s == '{': 8 print('<?xml version="1.0" encoding="UTF-8" ?>\n<data>') 9 elif s == '}': 10 print('</data>') 11 else: 12 m = re.search(r'\'(\w+)\':\s+(\w+)', s) 13 if m: 14 k, v = m.group(1), m.group(2) 15 print(f'<{k}>{v}</{k}>')

$ cat data.txt | python data2xml.py

xml

1<?xml version="1.0" encoding="UTF-8" ?> 2<data> 3<key1>value1</key1> 4<key2>value2</key2> 5<key1>value3</key1> 6</data>

$ pip install lxml xmljson

Collecting lxml
Using cached https://files.pythonhosted.org/packages/a7/85/8b1a9a33b451114e352c29a200320f086ea30ff163599dd39cb627e7c86a/lxml-4.5.0-cp37-cp37m-macosx_10_9_x86_64.whl
Collecting xmljson
Using cached https://files.pythonhosted.org/packages/e4/e6/f9cf79926273920d6091d706babc27989c3c1633de6ba6072157348ea3a8/xmljson-0.2.0-py2.py3-none-any.whl
Installing collected packages: lxml, xmljson
Successfully installed lxml-4.5.0 xmljson-0.2.0

$ cat xml2json.py

python3

1import sys 2from lxml import etree 3import xmljson 4import json 5 6tree = etree.parse(sys.stdin) 7 8dic = xmljson.yahoo.data(tree.getroot()) 9 10json.dump(dic, sys.stdout, indent=2) 11

$ cat data.txt | python data2xml.py | python xml2json.py > data.json

$ cat data.json

json

1{ 2 "data": { 3 "key1": [ 4 "value1", 5 "value3" 6 ], 7 "key2": "value2" 8 } 9}

上記では、data2xmlとdata2xml、ともにPythonで書きましたが、プログラミング言語として何を使うかは、この回答の本題ではなく、「中間形式としてXMLにしてみてはいかがでしょう?」というご提案が主旨になります。

また、上記のコードでは、XMLからJSONにするのに、xmljsonという既存モジュールを使いましたが、XMLをパースしてXPathで欲しい情報だけを拾って別の形式のJSONにすることもできます。このように、独自形式の元データをXMLに変換すれば、その後はXMLという汎用的な形式を処理するという、解法のヒントが多く得られる問題に置き換えることができるので、採り得る選択肢が広がるのではと考えた次第です。

以上、参考になれば幸いです。

投稿2020/04/07 21:24

jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

文字列処理するしかないので、こういうパターンを考えてみました。

javascript

1var code = `{ 2'key1': value1, 3'key2': value2, 4'key1': value3 5}` 6 7var parse = str => { 8 let oj = {}; 9 let set = (k,v) => { 10 if( ! oj.hasOwnProperty(k) ) oj[k] = v; 11 else if( !Array.isArray(oj[k]) ) { 12 oj[k] = [oj[k]]; 13 } 14 if( Array.isArray(oj[k]) ) oj[k].push(v); 15 } 16 17 str.split(/\x2c?\n/).forEach( token => { 18 console.log(" token ", token ); 19 let m; 20 if( m = token.match(/\x27([\w\d]+)\x27\x3a\s*([\w\d]+)/) ) { 21 console.log("pair-match ", m ); 22 set(m[1],m[2]); 23 } 24 }) 25 26 return oj; 27} 28 29var json = parse( code ); 30 31console.log( JSON.stringify(json,null,2) ); 32/* 33{ 34 "key1": [ 35 "value1", 36 "value3" 37 ], 38 "key2": "value2" 39} 40 */

投稿2020/04/07 11:10

AkitoshiManabe

総合スコア5434

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

 オブジェクト形式のデータに同名のkeyが使われていた場合

jsではオブジェクトに同名のキーは設定できません

投稿2020/04/07 10:26

yambejp

総合スコア116724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2020/04/07 10:32

JSONとの入出力は無理ですが、formdataで処理は可能です var fd=new FormData(); fd.append("hoge",1); fd.append("fuga",2); fd.append("hoge",3); console.log(fd.getAll("hoge"));
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問