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

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

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

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

JavaScript

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

Q&A

解決済

3回答

2058閲覧

多層構造のJSONの下層に含まれる特定の値を持つデータを抽出する

kaz33333

総合スコア2

JSON

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

JavaScript

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

0グッド

0クリップ

投稿2021/12/09 10:14

前提・実現したいこと

下記のようなJSONを取得して、表示を分ける処理をしています。

該当のソースコード

json

1 2var data =[ 3 { 4 "sname": "機能1", 5 "category": "カテゴリー1", 6 "label": [ 7 { "lname": "Aプラン"}, 8 { "lname": "Bプラン" }, 9 { "lname": "Cプラン"} 10 ] 11 }, 12 { 13 "sname": "機能2", 14 "category": "カテゴリー2", 15 "label": [ 16 { "lname": "Bプラン" }, 17 { "lname": "Cプラン"} 18 ] 19 }, 20 { 21 "sname": "機能3", 22 "category": "カテゴリー1", 23 "label": [ 24 { "lname": "Aプラン"}, 25 { "lname": "Bプラン" }, 26 { "lname": "Dプラン"} 27 ] 28 } 29]

試したこと

下記のようにfilterを使用してみましたが、うまくいきませんでした。
方法2でうまくいったと思ったのですが、同時に他の要素でフィルタリングしようと思った時に2つ目の要素以降がうまくいきません。

javascript

1 2 var p_data = JSON.parse(JSON.stringify(data)); 3 4 //Aプランのデータ抽出お試し 1 5 var aList = p_data.filter(function(item, index){ 6 if (item.label.lname == "Aプラン" ) return true; 7 }); 8 console.log(aList); 9//結果 NG 10//length: 0 11 12 //Aプランのデータ抽出お試し 2 13 var aList = p_data.filter(function(item, index){ 14 if (item.label[0].lname == "Aプラン" ) return true; 15 }); 16 console.log(aList); 17//結果 OK 18//0: 19//category: "カテゴリー1" 20//label: (3) [{…}, {…}, {…}] 21//sname: "機能1" 22//1: 23//category: "カテゴリー1" 24//label: (3) [{…}, {…}, {…}] 25//sname: "機能3" 26 27 //同様にBプランの抽出データも作りたい 28 var bList = p_data.filter(function(item, index){ 29 if (item.label[0].lname == "Bプラン" ) return true; 30 }); 31 console.log(bList); 32//結果 NG 1つしか値が返されない 33//0: 34//category: "カテゴリー2" 35//label: (2) [{…}, {…}] 36//sname: "機能2" 37 38

やりたいこと

最終的にはAプランを値に含む配列、Bプランを値に含む配列、Cプランを値に含む配列をそれぞれ作成し、
Click操作で表示を出し分ける処理を行いたいと思っています。
良いやり方があれば教えていただければ幸いです。
宜しくお願い致します。

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

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

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

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

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

kei344

2021/12/09 12:35

まだ質問が「受付中」になっていますが、「ベストアンサー」を選び「解決済」にされてはいかがでしょうか。
kaz33333

2021/12/09 14:28

teratailの操作に慣れておらず、対応が遅く申し訳ありません。 ご指摘ありがとうございました。
guest

回答3

0

ベストアンサー

一案としては、aList の作り方を以下

javascript

1var aList = p_data.filter(function(item, index) { 2 return item.label.some(({ lname }) => lname.startsWith("A")); 3});

のようにします。そうすると、これに倣ってbList は、上記のコードの中の"A" を "B" にした

javascript

1var bList = p_data.filter(function(item, index) { 2 return item.label.some(({ lname }) => lname.startsWith("B")); 3});

で作れます。cList, dList も同様です。

さらに、同じようなコードを4回繰り返すのを避けるために、配列のmapメソッドを使うことで、得たい4つの配列を一度に作ることができます。以下はその例です。(map と filter に渡す関数にアロー関数を使用しています。)

javascript

1const [aList, bList, cList, dList] = ['A', 'B', 'C', 'D'].map( 2 x => p_data.filter(item => item.label.some(({ lname }) => lname.startsWith(x))) 3);

投稿2021/12/09 11:12

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kaz33333

2021/12/09 12:29

ありがとうございます! 教えていただいたやり方で、希望する配列が作れました。 mapメソッドの使い方も勉強になりました。
guest

0

js

1let list = { }; 2for (let rec of data) 3 for (let {lname} of rec.label) 4 list[lname] = (list[lname] || []).concat (rec); 5 6console.log (list);

Array.filter に拘るのは無駄。

js

1<!DOCTYPE hrml> 2<meta charset="UTF-8"> 3<title></title> 4 5<body> 6<select id="hoge"><option></option></select> 7<table border="1" id="fuga"></table> 8 9<script> 10var data =[ 11 { 12 "sname": "機能1", 13 "category": "カテゴリー1", 14 "label": [ 15 { "lname": "Aプラン"}, 16 { "lname": "Bプラン" }, 17 { "lname": "Cプラン"} 18 ] 19 }, 20 { 21 "sname": "機能2", 22 "category": "カテゴリー2", 23 "label": [ 24 { "lname": "Bプラン" }, 25 { "lname": "Cプラン"} 26 ] 27 }, 28 { 29 "sname": "機能3", 30 "category": "カテゴリー1", 31 "label": [ 32 { "lname": "Aプラン"}, 33 { "lname": "Bプラン" }, 34 { "lname": "Dプラン"} 35 ] 36 } 37]; 38 39let list = { }; 40for (let rec of data) 41 for (let {lname} of rec.label) 42 list[lname] = (list[lname] || []).concat (rec); 43 44 45for (let k of Object.keys (list)) 46 hoge.appendChild (new Option (k)); 47 48hoge.addEventListener ('change', (e,p=list[e.target.value])=> { 49 [...fuga.children].forEach (e=>e.remove()); 50 !p || ary2tbody (p.map (p=> Object.entries (p).map (([k,v])=> Array.isArray (v) ? v.map(v=>v.lname).join(', '):v)), fuga); 51}); 52 53function ary2tbody (a, b=document.createElement('tbody')) { 54 return a.reduce((b,c)=>(c.reduce((c,d)=>(c.insertCell().textContent=d,c),b.insertRow()),b),b); 55} 56 57 58</script> 59

投稿2021/12/09 10:54

編集2021/12/09 11:56
babu_babu_baboo

総合スコア616

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

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

kaz33333

2021/12/09 13:23

ありがとうございます。 具体的な表示例まで記載いただき、助かります。 記載いただいた事例のコードを応用して、selectではなくクリックで切り替えられるように実装しようとしたのですが、つまずいてしまいました。 for (let k of Object.keys (list)) hoge.appendChild (new Option (k)); のところを、 for (let k of Object.keys (list)) { var li_element = document.createElement('li'); li_element.textContent = k; parent.appendChild(li_element); } と、リスト表示するところまではできたのですが、 以下の処理をクリックイベントに変更することができずにいます。 hoge.addEventListener ('change', (e,p=list[e.target.value])=> { [...fuga.children].forEach (e=>e.remove()); !p || ary2tbody (p.map (p=> Object.entries (p).map (([k,v])=> Array.isArray (v) ? v.map(v=>v.lname).join(', '):v)), fuga); }); mapでkeyと値のセットを作って表示する・・みたいな感じでしょうか。 理解が浅く、申し訳ありません。。
kaz33333

2021/12/09 14:25

取り急ぎ、特定のIDのついたボタンをクリックすると参照データにそれぞれ目的の配列を渡すみたいなやり方で解決いたしました。 時間のある時にいただいたコードを分析して、しっかり勉強していきたいと思います。 この度はありがとうございました。
babu_babu_baboo

2021/12/09 19:42

hoge.addEventListener ('click', (e,p=list[e.target.textContent])=> { [...fuga.children].forEach (e=>e.remove()); !p || ary2tbody (p.map (p=> Object.entries (p).map (([k,v])=> Array.isArray (v) ? v.map(v=>v.lname).join(', '):v)), fuga); });
guest

0

labelは配列なので、[0]だけじゃなくて全部調べないと。

JavaScript

1 var aList = p_data.filter( 2 item => item.label.find( x => x.lname == "Bプラン") 3 ); 4 console.log(aList);

書き方も少しコンパクトにしました。

投稿2021/12/09 10:41

otn

総合スコア85901

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

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

kaz33333

2021/12/09 13:27

こちらのやり方でも抽出できました。 基礎的な理解が曖昧でどう処理していいかわからなかったことを具体的に教えていただき、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問