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

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

ただいまの
回答率

87.79%

読み込んだjsonファイルをjqueryでフィルタリング処理

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,131

score 21

 前提・実現したいこと

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.length; i++){
     $('<li><img src="'+filterdata[i].url+' " /><p>'+filterdata[i].caption+'</p></li>').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/

何卒よろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

こんにちは。
 
フィルタリングされた配列を作るところで、$.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 に写し、上記の修正をしたものが以下です。
(※画像はありません)
 
http://jsfiddle.net/jun68ykt/8fm81f8z/4/


追記

以下補足です。

修正前の 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"


とが違う結果を返すことが確認できます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/11 11:09

    ご教授いただき誠にありがとうございました。
    意図した通りになりました。

    キャンセル

  • 2018/02/11 11:12 編集

    補足として、=== と == について追記しました。ひとまず解決されたようですね、良かったです!

    キャンセル

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

  • ただいまの回答率 87.79%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る