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

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

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

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

JavaScript

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

Q&A

解決済

2回答

1857閲覧

Jsonの中身を乱数によって取り出したい。

dice.

総合スコア2

JSON

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

JavaScript

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

1グッド

1クリップ

投稿2022/10/20 06:11

編集2022/10/20 11:13

JavaScriptでJsonに格納されているデータを取得したい。
が、途中でundefinedとなってしまい、立ち行かなくなってしまった。

実現したいこと

複数存在するデータの中からランダムに取り出したいので、regionの数を取得して、
その数の乱数を出力し、対応するデータの中身を取り出したい。

発生している問題・エラーメッセージ

const max = num.region.length ^ TypeError: Cannot read property 'length' of undefined

該当のソースコード

JavaScript

1const dummy = require("./dummy,json"); 2const num =dummy.hoge.filter(function(item, index){ 3 if(item.no == "001") return true; 4 }); 5 for( var i = 0; i < num.length; i++ ){ 6 console.log(JSON.stringify(num[i].date)); 7 const p = JSON.stringify(num[i].date); 8 const max = num.region//.length 9 const array = [] 10 console.log(max); 11 12 array.push(Math.floor(Math.random() * max) + 1); 13 14 const regclass = num.filter(function(item, index){ 15 if(num.region == num + array) return true; 16 }); 17 console.log(regclass); 18 }

Json

1{ 2 "hoge":[ 3 { 4 "no":"001", 5 "date":[ 6 { 7 "region":"001-1", 8 "detail":{ 9 "name":"タナカ", 10 "type":"C", 11 "weight":"40kg", 12 "height":"177m", 13 }, 14 "region":"001-2", 15 "detail":{ 16 "name":"ヨシダ", 17 "type":"C", 18 "weight":"53kg", 19 "height":"164m", 20 }, 21 "region":"001-3", 22 "detail":{ 23 "name":"サトウ", 24 "type":"C", 25 "weight":"70kg", 26 "height":"180m", 27 } 28 } 29 ] 30 } 31 ] 32}

試したこと

Json内の[]を外し、動作を確認。
num[i].date.regionでも同様にエラーが出るので、そもそもjsonに理解が足りていない気がするのですが、検索してもそれらしい答えに辿り着けず…。

補足情報(FW/ツールのバージョンなど)

node v12

追記. 10/22 20:10

指摘された通り、JSONに対する理解不足で詰まってました。
解決致しましたので、質問箇所以外のコードについても丁寧に指摘いただいた方をBAとして閉めさせていただきます。
ありがとうございました。

Cocode👏を押しています

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

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

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

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

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

int32_t

2022/10/20 06:31

例示されているJSONは .hoge[0].date[0] の1つのオブジェクトに region プロパティと detail プロパティが3つずつあっておかしいですね。
dice.

2022/10/20 10:45

コメントありがとうございます。 1つのオブジェクトに入っている場合、後から指定されたもので上書きされるのですね…。 シンプルに勉強不足でした、ありがとうございます。
guest

回答2

0

特定のオブジェクトの中に同じキーを指定するとあとから指定したもので上書きされます

javascript

1const obj={a:1,b:2,a:3,b:4,a:5,b:6}; 2console.log(obj); // {a:5,b:6}

おそらくjsonデータの作り方が間違えているのでしょう。
もしこんなふうなjsonデータとしたらregionはこうやって得てください

javascript

1const json={ 2 "hoge":[ 3 { 4 "no":"001", 5 "date":[ 6 { 7 "region":"001-1", 8 "detail":{ 9 "name":"タナカ", 10 "type":"C", 11 "weight":"40kg", 12 "height":"177m", 13 } 14 },{ 15 "region":"001-2", 16 "detail":{ 17 "name":"ヨシダ", 18 "type":"C", 19 "weight":"53kg", 20 "height":"164m", 21 } 22 },{ 23 "region":"001-3", 24 "detail":{ 25 "name":"サトウ", 26 "type":"C", 27 "weight":"70kg", 28 "height":"180m", 29 } 30 } 31 ] 32 } 33 ] 34} 35const getAllValues=(x)=>{ 36 var ret=[]; 37 Object.entries(x).forEach(y=>{ 38 if(y[1] instanceof Object){ 39 ret=ret.concat(getAllValues(y[1])); 40 }else{ 41 ret.push(y); 42 } 43 }); 44 return ret; 45}; 46console.log(getAllValues(json).filter(x=>x[0]=="region").map(x=>x[1]));

投稿2022/10/20 08:35

編集2022/10/20 08:42
yambejp

総合スコア114769

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

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

dice.

2022/10/20 11:07

実例付きでjsonのオブジェクトについて解説いただき、ありがとうございます。 jsonの理解不足で煮詰まっていたので、勉強不足を痛感します。 提示していただいたコードを用いて、正しく動作しました。ありがとうございました。
guest

0

ベストアンサー

不具合の原因

  • JSONは一定の法則性によって書かれたただの文字列です。基本的にJSONデータを取得してきたら、JavaScriptで利用できるようにすぐに展開します。
    • JSON.parse(jsonの文字列): これでJSON形式の文字列が→JSのオブジェクトに変換されます。
    • JSON.stringify(JSのオブジェクト): これでJSのオブジェクト→JSON形式の文字列に変換されます。
    • 質問者様は文字列化してしまっていますので、オブジェクトではありませんから、正常に動作しません。
  • 提示されているダミーのオブジェクトの構造がおかしいです。
    • data: [{region, detail, region, detail, region, detail}]となっているので、最後に書いたもので上書きされているだけです。(つまりregion 001-3の内容とそのdetailしか残っていない。)
    • data: [{region, detail}, {region, detail}, {region, detail}]と修正しました。
    • 不具合の原因ではないですが、表現として気になったのは、date(日付)じゃなくてdata(データ)に変更させていただきました。
  • 不具合の原因ではないですが、無駄なのが、for( var i = 0; i < num.length; i++ )で繰り返し処理をしていることです。
    • no: '001'は1つしかないと思うので、numのlengthは1です。
    • それともno: '001'が何個も存在するのでしょうか?今のところこのナンバーはIDのような固有番号だと解釈しています。
  • 乱数を生成する時にMath.floor(Math.random() * max) + 1と、最後に+1をしていますが、
    • これでは最小値が1・最大値が3になってしまいます。
    • dataはlengthが3、つまりインデックスは0〜2なので、3は範囲外です。
    • +1を削除して乱数の範囲が最小値が0・最大値が2になるようにしましょう。

コード例

動作確認用サンプル:https://jsfiddle.net/tdL491nu/

javascript

1// const json = require("./dummy.json"); // コンマjsonじゃなくてドットjsonです 2const json = `{ 3 "hoge":[ 4 { 5 "no":"001", 6 "data":[ 7 { 8 "region":"001-1", 9 "detail":{ 10 "name":"タナカ", 11 "type":"C", 12 "weight":"40kg", 13 "height":"177m" 14 } 15 }, 16 { 17 "region":"001-2", 18 "detail":{ 19 "name":"ヨシダ", 20 "type":"C", 21 "weight":"53kg", 22 "height":"164m" 23 } 24 }, 25 { 26 "region":"001-3", 27 "detail":{ 28 "name":"サトウ", 29 "type":"C", 30 "weight":"70kg", 31 "height":"180m" 32 } 33 } 34 ] 35 } 36 ] 37}`; 38const dummy = JSON.parse(json); // JSONデータを展開するならこの時点でする 39 40const num = dummy.hoge.filter(obj => obj.no === '001'); 41// [{no: '001', data; [{...}, {...}, [...}]}] 42 43const data = num[0].data; 44// [{...}, {...}, [...}] 45 46const randomIdx = Math.floor(Math.random() * data.length); 47// 0〜2 48 49const result = data[randomIdx]; 50console.log(result); 51// 例 {region: '001-2', detail: {…}}

投稿2022/10/20 08:26

編集2022/10/20 08:27
Cocode

総合スコア2314

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

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

dice.

2022/10/20 11:00

回答ならびに、丁寧に解説していただきありがとうございます。 例示いただいたコードを用いて実装したかったことが実現出来そうです。 また、質問事項以外の部分も懇切丁寧に指摘いただいて痛み入ります。 大変勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問