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

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

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

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

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

1424閲覧

JSON内にある特定値の件数または値そのものを重複除去して表示したい

southern_flavor

総合スコア70

JSON

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

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2020/05/11 17:36

編集2020/05/11 17:38

#実現したいこと
JSONにて返ってくる値を次のような出力形式にしたいです。

地方: 東北 現在の表示中の都道府県: 宮城(2件) 秋田(1件) 名物: 牛タン 名物: 気仙沼ホルモン 名物: きりたんぽ 地方: 関東 現在の表示中の都道府県: 東京(1件) 埼玉(2件) 名物: 東京ばなな 名物: 草加せんべい 名物: さつまいも料理

JSONはこちらです。

JSON

1[ 2 { 3 "region": "東北", 4 "detail": [ 5 { 6 "pref": "宮城", 7 "product": "牛タン" 8 }, 9 { 10 "pref": "宮城", 11 "product": "気仙沼ホルモン" 12 }, 13 { 14 "pref": "秋田", 15 "product": "きりたんぽ" 16 } 17 ] 18 }, 19 { 20 "region": "関東", 21 "detail": [ 22 { 23 "pref": "東京", 24 "product": "東京ばなな" 25 }, 26 { 27 "pref": "埼玉", 28 "product": "草加せんべい" 29 }, 30 { 31 "pref": "埼玉", 32 "product": "さつまいも料理" 33 } 34 ] 35 } 36]

#発生しているエラー

Uncaught TypeError: Cannot convert undefined or null to object

#ソースコード
特定のkeyにある件数を取得するために、Object.keys().lengthなども使いましたが、うまくいかなったです。
ソースよりもJSONの形式を直した方が効率が良い等、、アドバイスや解決策等をご教授いただけたら幸いです。

上記出力形式にある「(●件)」というのは配列の中にある特定ワードの件数を自動で取得するようにしたいです。
「現在表示中の都道府県: 」のところは重複を除去したうえでdetail内にあるものをすべて表示したいと思っています。

javascript

1 const jsonUrl = "json_url"; 2 function getData(jsonPath = '') { 3 return $.ajax({ 4 type: 'GET', 5 url: jsonPath, 6 cache: false, 7 }) 8 } 9 function shopLoop(jsondata = '') { 10 var h = ''; 11 for(var i in jsondata){ 12 13 h += '<h3>地方:' + jsondata[i].region + '</h3>'; 14 h += '<div>'; 15 h += '<div>'; 16 for(var j in jsondata[i].detail){ 17 18 if ( jsondata[i].detail[j].pref !== -1 ) { 19 h += '<p>現在表示中の都道府県: ' + jsondata[i].detail[j].pref + '(' + Object.keys( jsondata[i].detail[j].pref ).length + '件)' + '</p>'; 20 } 21 h += '<div><ul>'; 22 h += '<li>名物:' + jsondata[i].detail[j].shop_name + '</li>'; 23 h += '</ul>'; 24 h += '</div>'; 25 } 26 h += '</div>'; 27 h += '</div>'; 28 } 29 $('#hoge').html(h); 30 } 31 32 33 getData(jsonUrl).then( function(data) { 34 shopLoop(data); 35 }); 36

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

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

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

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

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

okina

2020/05/11 19:04

このエラーはどの部分で発生しているものですか? Nullか未定義のオブジェクトとのことなので、もっと根本的なことな気もします
southern_flavor

2020/05/12 06:47 編集

エラーに関しては Object.keys( jsondata[i].detail[j].pref ).length の箇所で発生しております。 ご回答をいただいたので、解決策がみえてきました。
guest

回答2

0

ベストアンサー

こんにちは

json

1[ 2 { 3 "pref":"東京", 4 "product":"東京ばなな" 5 }, 6 { 7 "pref":"埼玉", 8 "product":"草加せんべい" 9 }, 10 { 11 "pref":"埼玉", 12 "product":"さつまいも料理" 13 } 14]

というJSONがパースされて得られる配列 detail から、以下のような文字列

text

1埼玉(2件) 東京(1件)

を得ることが、ご質問の主題と理解しました。この場合、配列の要素の prefプロパティの値ごとにグルーピングして、かつ、グループごとの件数を数えればよいです。

そこで、まず以下のようなオブジェクト(名前を counts とします)を得ることを考えます。

javascript

1{ '東京': 1, '埼玉': 2 }

上記を得るために、自力でプログラムを書いてもよいですが、配列やオブジェクトの操作で便利なライブラリの力を借ります。具体的には lodash の _.groupBy_.mapValues を使います。以下で counts が得られます。

javascript

1const counts = _.mapValues(_.groupBy(detail, "pref"), 'length');

次に、 counts から、件数の多い順にソートされた、都道府県名と件数のペアの配列 sortedCounts を作ります。それには以下のようにします。

javascript

1const sortedCounts = Object.entries(counts).sort((e1, e2) => e2[1]-e1[1]);

これで、sortedCounts には以下の配列が得られます。

javascript

1[ ['埼玉', 2], ['東京', 1] ]

最後に、 sortedCountsを使って、

javascript

1sortedCounts.map(([pref, count]) => `${pref}(${count}件)`).join(' ');

とすると、

text

1埼玉(2件) 東京(1件)

という文字列が得られます。

以下は上記のコードを関数 function prefsInfo(detail) にまとめたサンプルです。

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

追記

「product」の中身が空だった場合、liタグごと削除し、「product」が存在している場合はそのまま表示したいです。

上記の対応として、以下のように、map に与える関数の返り値を作るところで、=>`<li>名物 の間に e.product && を追加してみるといかがでしょうか?

diff

1- const items = detail.map(e => `<li>名物: ${e.product}</li>`).join(''); 2+ const items = detail.map(e => e.product && `<li>名物: ${e.product}</li>`).join('');

投稿2020/05/12 00:42

編集2020/05/12 07:28
jun68ykt

総合スコア9058

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

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

southern_flavor

2020/05/12 07:11

前回に引き続き、たいへん詳しく教えていただきありがとうございます。 Lodash.jsを知らなかったので参考になりました。 想定通りの動きになりました。 すみません、最後にcodepenにあった以下のmap()内部で条件式を使用するにはどのようにしたらよろしいでしょうか? const items = detail.map(e => `<li>名物: ${e.product}</li>`).join(''); JSONにて、「product」の中身が空だった場合、liタグごと削除し、「product」が存在している場合はそのまま表示したいです。 こちらで書いてみたのですが、何も表示されなくなってしまいます。 const items = detail.map(function(e){ if(e.product) { '<li>名物: ${e.product}</li>' } } ).join('');
jun68ykt

2020/05/12 07:36 編集

コメントありがとうございます。 lodash には多くの便利なメソッドがありますが、いっぺんに覚えようとすると大変なので、 ちょっとずつ今回のご質問のような機会ごとに使い始めていけばよいかと思います。 > JSONにて、「product」の中身が空だった場合、liタグごと削除し、「product」が存在している場合はそのまま表示したいです。 の件ですが、そのコード const items = detail.map(function(e){ if(e.product) { '<li>名物: ${e.product}</li>' } } ).join(''); だと、map に与えている関数に、returnが書かれていないので、detail の要素個数分の undefined の配列がmapによって作られて、それを空文字列で joinするので、結果として、空文字列になります。 では、どのように修正するかの一例を回答に追記しました。参考になれば幸いです。
southern_flavor

2020/05/12 17:23

最後まで詳しく教えていただき、ありがとうございます! おかげさまで空の値に対する判定もうまくできました。 まだわからない点はいくつかありますが、ライブラリも調べてやってみます。 ありがとうございました。
jun68ykt

2020/05/13 11:15

どういたしまして???? > おかげさまで空の値に対する判定もうまくできました。 とのことでよかったです????
guest

0

明確な回答になっていなくてすみません。
参考までに記載いたします。

Lodash.js なんかを使用してみてはいかがでしょうか?

_.uniq(array) : 重複排除。
_.size(array) : カウント

投稿2020/05/11 23:54

newdaysys

総合スコア40

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

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

southern_flavor

2020/05/12 06:48

ご回答とアドバイスをいただき、ありがとうございます。 恥ずかしながらそのライブラリは知らなかったので使ってみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問