質問: ### 前提・実現したいこと jsonファイルを読み込み、例えばカテゴリごとに表示することを行おうとしておりますが、うまく実現ができません。 CODEPENにソースをアップしております。 https://codepen.io/m_a_u_v_e/pen/vdmYgX 1. jsonファイルの"category"によってフィルタリングをしたいと思っておりまして、 categoryは複数に設定可能の仕様になっています。 [ { "category": ["cafe", "autum"], "caption": "カフェ ", "url": "http://jsrun.it/assets/3/o/C/A/3oCAy.jpg" }, { "category": ["autum"], "caption": "紅葉", "url": "http://jsrun.it/assets/y/c/W/i/ycWii.jpg" }, ・・・続く・・・ ] 1. htmlファイルはラジオボタンにしてあり、valueの値で表示するカテゴリを判別します。 ### 該当のソースコード ``` //変数設定 var $imageWrap=$("#imageWrap"); var alldata=[]; //ここはすべてのデータを保持しておく配列 var filterdata=[]; //フィルターを掛けたデータを保持する配列 //最初に読み込んだ時に発生する関数 $.getJSON('http://jsrun.it/assets/c/s/y/n/csynt',init); function init(data){ //全データを保持しておく alldata=data; //とりあえず全データを代入しておく filterdata=alldata; //データを表示させる display(); } //画像表示させるための関数 function display(){ $imageWrap.empty(); for(var i=0; i'+filterdata[i].caption+'').appendTo($imageWrap); } } //ラジオボタンが変わった時にフィルタリングする関数 $('input:radio').change(function(){ //チェックボタンの状況によってフィルタリングする var cate=$(this).val(); //フィルターの配列をいったん空っぽにする filterdata=[]; if(cate==="all"){//allが選択されたら全データを保持 filterdata=alldata; }else{ filterdata=$.grep(alldata,function(n){ return n.category===cate; }); } display(); }); ``` ### 補足情報 仕組み自体は下記の記事を参考にしておりまして、 categoryが複数の場合での分岐方法が不明のため、 ご教授頂きたくお願いいたします。 http://the-zombis.sakura.ne.jp/wp/blog/2014/01/03/post-2094/ 何卒よろしくお願いいたします。
回答: こんにちは。 フィルタリングされた配列を作るところで、`$.grep` を使っていますが、 これに渡す関数が返す真偽値(の式)を、以下のように修正するとよいでしょう。 **修正前:** ``` filterdata = $.grep(alldata,function(n){ return n.category === cate; }); ``` これを、indexOfを使って、 **修正後:** ``` filterdata = $.grep(alldata,function(n){ return n.category.indexOf(cate) >= 0; }); ``` とするか、あるいは、includesを使って、以下のようにします。 **修正後:** ``` filterdata = $.grep(alldata,function(n){ return n.category.includes(cate); }); ``` 参考までに、ご提示のコードを jsFiddle に写し、上記の修正をしたものが以下です。 (※画像はありません) **追記** 以下補足です。 修正前の `return` で返される式 ``` n.category === cate ``` が `true` になることはありません。 なぜなら、`===` が `true` になるためには、両辺の型が同じであることが必要ですが、 `n.category` は配列(Array)で、 `cate` は文字列(String)だからです。 ここで試しに、 `=` をひとつ減らした ``` n.category == cate ``` として、ご質問のコードを実行して autum のラジオボタンをクリックしてみると、 API から返された ``` [ { "category": ["cafe", "autum"], "caption": "カフェ、秋", "url": "http://jsrun.it/assets/3/o/C/A/3oCAy.jpg" }, { "category": ["autum"], "caption": "紅葉", "url": "http://jsrun.it/assets/y/c/W/i/ycWii.jpg" }, { "category": ["tokyo"], "caption": "東京駅", "url": "http://jsrun.it/assets/n/O/V/x/nOVx2.jpg" }, { "category": ["autum"], "caption": "紅葉2", "url": "http://jsrun.it/assets/h/I/X/B/hIXBO.jpg" }, { "category": ["tokyo"], "caption": "東京タワー", "url": "http://jsrun.it/assets/j/S/t/n/jStnu.jpg" } ] ``` のうち、 * `"caption": "紅葉"` と `"caption": "紅葉2"` は表示されるが、 * `"caption": "カフェ、秋"` のデータは表示されない。 という結果になります。望ましいのは、上記の3つとも表示されてほしいわけですが、 以下、このような結果になる理由を説明します。 まず、 * `"caption": "紅葉"` と `"caption": "紅葉2"` は表示される 理由は、以下の判定が `true`**になる**からです。 ``` ["autum"] == "autum" ``` 上記で、左辺の `["autum"]` は、 `==` の右辺が文字列なので、 比較される前に文字列に変換されて、`"autum"`となるので、 `==` の結果が true になります。 次に、 * `"caption": "カフェ、秋"` のデータは表示されない。 のは何故かといえば、以下が `true` には**ならない**からです。 ``` ["cafe", "autum"] == "autum" ``` 上記の左辺は、やはり比較の前に文字列に変換されますが、左辺が文字列になると `"cafe,autum"` に変換され、右辺とは異なる文字列なので `==` は`false`を返します。 このように `===` を `==` に変えてみることで、 ``` ["autum"] === "autum" ``` と、 ``` ["autum"] == "autum" ``` とが違う結果を返すことが確認できます。