###実現したいこと
JavaScriptにてJSONを検証したいのですがお手伝い頂けませんでしょうか。
以下jsfiddle冒頭に書いたのですが、
https://jsfiddle.net/a19bvp4e/
var current_search_menus = {} について var default_search_menus = {} と同じ構造であることを検証したい
というのが目的です。
つまり、81行目のvalidate_current_search_menus()
の書き方を知りたいのですが、どのように書くのがいいでしょうか。
###該当のソースコード
先のjsfiddleのソースコードになります。
jQuery
1/* 2 var current_search_menus = {} について 3 var default_search_menus = {} と同じ構造であることを検証したい 4 5 具体的な検証内容は次の2つ 6 7 【検証1】 8 default_search_menus に存在するキーだけで 9 current_search_menus が構成されていることを検証したい 10 (深い階層まで同じキーであることを検証したい) 11 12 【検証2】 13 search_pages:{この中} 14 の中に1つだけ "key": true があることを検証したい 15 16 【検証3】 17 posts:{この中}, comments:{この中}, users:{この中} 18 の中にそれぞれ1つずつ "key": true があることを検証したい 19*/ 20 21// 検証したい値(ユーザーが選択したラジオボタンがローカルストレージに保存されたもの) 22var current_search_menus = { 23 // 【検証1】default_search_menus と同じキーである 24 "search_pages": {"posts":true,"comments":false,"users":false}, // 【検証2】true は search_pages:{この中} に1つだけ 25 "search_filter": { 26 "posts": { 27 "dog": { 28 "a": false, // 【検証3】true は posts:{この中} の中に1つだけ 29 "n": true, 30 } 31 }, 32 "comments": { 33 "cat": { 34 "c": true, // 【検証3】true は comments:{この中} の中に1つだけ 35 } 36 }, 37 "users": { 38 "giraffe": { 39 "a": false, 40 "r": true, // 【検証3】true は users:{この中} の中に1つだけ 41 "v": false, 42 }, 43 "frog": { 44 "r": false, 45 "t": false, 46 }, 47 }, 48 } 49}; 50 51// デフォルトの値(PHPからprintしてJSで変数として持っている値) 52var default_search_menus = { 53 "search_pages": {"posts":false,"comments":false,"users":true}, 54 "search_filter": { 55 "posts": { 56 "dog": { 57 "a": true, 58 "n": false, 59 } 60 }, 61 "comments": { 62 "cat": { 63 "c": true, 64 } 65 }, 66 "users": { 67 "giraffe": { 68 "a": true, 69 "r": false, 70 "v": false, 71 }, 72 "frog": { 73 "r": false, 74 "t": false, 75 }, 76 }, 77 } 78}; 79 80// 検証を実行 81function validate_current_search_menus(current_search_menus){ 82 83 // 現状はわからないのでランダムに返す 84 var b = [true,false]; 85 var is_all_ok = Math.floor( Math.random() * b.length ); 86 return is_all_ok; 87 88} 89 90// ユーザーが選択した項目を取得 91var result = get_selected_search_menu(current_search_menus); 92console.log('result=',result); 93function get_selected_search_menu(current_search_menus){ 94 95 /* 96 このタイミングで【検証1、2、3】を実行すべく 97 validate_current_search_menus を通し 98 current_search_menus が正しいかどうか 99 ( is_all_ok = true かどうか ) を確認します 100 101 もし正しくなければ ( is_all_ok = false なら ) 102 current_search_menus でなく 103 default_search_menus を使って以下の処理を続けるようにしたいです 104 */ 105 const is_all_ok = validate_current_search_menus(current_search_menus); 106 if( is_all_ok ){ 107 search_menus = current_search_menus; 108 }else{ 109 search_menus = default_search_menus; 110 } 111 112 let result = {}; 113 114 let search_page = ''; 115 const search_pages = search_menus.search_pages; 116 $.each(search_pages, function(page_name,state){ 117 if(state === true){ 118 search_page = page_name; 119 } 120 }); 121 122 const search_filter = search_menus.search_filter[search_page]; 123 $.each(search_filter, function(name,obj){ 124 $.each(obj, function(kind,state){ 125 if(state === true){ 126 result = {name,kind}; 127 } 128 }); 129 }); 130 131 return result; 132} 133 134
###試したこと
81行目のvalidate_current_search_menus()
ですが、自分なりにキーを一つずつcheck_same_keys
で検証するという方法で書いてみました。
しかし、
・最後のis_single_true
だけがうまくいきません…
・そしてコードが冗長すぎて嫌になってきます…
ので、この2点の改善のお願いできればと思っています。
jQuery
1 2// 検証を実行 3function validate_current_search_menus(current_search_menus){ 4 5 // 現状はわからないのでランダムに返す 6 // var b = [true,false]; 7 // var is_ok = Math.floor( Math.random() * b.length ); 8 // return is_ok; 9 10 // キーが同じであることを確認 11 const check_same_keys = function(target_obj,default_obj){ 12 const current_keys = Object.keys(target_obj); 13 const default_keys = Object.keys(default_obj); 14 const is_same_keys = JSON.stringify(current_keys.sort()) === JSON.stringify(default_keys.sort()); 15 return is_same_keys; 16 } 17 18 // 【検証1】 19 const is_same_keys0 = check_same_keys(current_search_menus.search_filter,default_search_menus.search_filter) 20 console.log('is_same_keys0=',is_same_keys0); 21 22 const is_same_keys1 = check_same_keys(current_search_menus,default_search_menus); 23 console.log('is_same_keys1=',is_same_keys1); 24 25 let is_same_keys2 = false, 26 is_same_keys3 = false; 27 28 const ok_search_page_arr = Object.keys(default_search_menus.search_filter); 29 ok_search_page_arr.forEach(function(search_page){ 30 const target_search_filter = current_search_menus.search_filter[search_page]; 31 const default_search_filter = default_search_menus.search_filter[search_page]; 32 const is_same_keys2 = check_same_keys(target_search_filter,default_search_filter); 33 console.log('is_same_keys2=',is_same_keys2); 34 35 $.each(target_search_filter, function(name,obj){ 36 const default_obj = default_search_menus.search_filter[search_page][name]; 37 const is_same_keys3 = check_same_keys(obj,default_obj); 38 console.log('is_same_keys3=',is_same_keys3); 39 }); 40 }); 41 42 // 【検証2、3】 43 let is_single_true = true; 44 ok_search_page_arr.forEach(function(search_page){ 45 const search_filter = current_search_menus.search_filter[search_page]; 46 $.each(search_filter, function(name,obj){ 47 let count_true = 0; 48 $.each(obj, function(kind,state){ 49 if(state === true){ 50 count_true = count_true + 1; 51 } 52 }); 53 if( count_true !== 1 ){ 54 is_single_true = false; 55 return; 56 } 57 console.log('count_true=',count_true); // ここが1なのになぜか is_single_true=false になってしまう 58 }); 59 }); 60 console.log('is_single_true=',is_single_true); 61 62 const is_all_ok = is_same_keys0 && is_same_keys1 && is_same_keys2 && is_same_keys3 && is_single_true; 63 return is_all_ok; 64 65}
お時間ございましたらご回答いただけますと幸いです。
どうぞ宜しくお願い致します。
###条件
・jQueryだけで実装したいということもなく、JavaScriptでも問題ございません。
・外部のライブラリ(JSONスキーマなど)は使用せずに実装したいです。
回答3件
あなたの回答
tips
プレビュー