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

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

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

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

JavaScript

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

Q&A

解決済

2回答

9746閲覧

JSでJSONを動的にフィルタしたい

Pltcpx

総合スコア7

JSON

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

JavaScript

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

0グッド

0クリップ

投稿2019/09/19 05:03

編集2019/09/19 06:09

JSでJSONを動的にフィルタしたい

let products = [ {name:"iphone11Pro", price:100000, delv:0, isSale:false, isUsed: false}, {name:"iphone11", price:90000, delv:0, isSale:false, isUsed: false}, {name:"iphoneXS", price:80000, delv:0, isSale:false, isUsed: false}, {name:"iphoneXR", price:80000, delv:0, isSale:true, isUsed: false}, {name:"iphone8", price:70000, delv:500, isSale:true, isUsed: false}, {name:"iphone7", price:60000, delv:500, isSale:true, isUsed: true}, {name:"iphoneSE", price:50000, delv:0, isSale:true, isUsed: true}, ]

上記のようなJSONがあり、Objectのkeyは今後も増え、絞り込み条件(かつ)も増えるので、動的に絞り込み条件を生成し、フィルタしたいと思っています。


Vue.jsで画面側をJSONに連動して変更しようと思っており、「商品リスト」と「チェックボックスによる絞り込み機能」を考えています。
画面側に「セール品絞り込みチェックボックス」「中古品絞り込みチェックボックス」などがあり、今後も「〜〜絞り込みチェックボックス」(と対応するkey)が増えることを想定しています。
なので、ベタにアンド条件を書きたくないと思い、動的に絞り込み条件をつくってフィルタする機能を作りたいです。


なので、下記ソースコードのように

  • 文字列で条件文を生成
  • eval(またはFunction)につっこんでfilter関数で実行

しようと思っているのですが、動的な条件によるJSONの絞り込みでもっとスマートな方法があれば教えてくださいませんでしょうか。
この方法でもいい場合、こういったケースでevalで気をつけることがあれば教えてください。

該当のソースコード

JavaScript

1 2//条件文の文字列の生成コード 絞り込み条件に応じて条件文を構築(関数詳細省略) 3 4let condition = getConditionText(); 5 6//生成された文字列 7console.log(condition); 8// "item.delv > 0 && item.isSale == true && item.isUsed == true" 9 10//フィルタ 11let filteredProducts = products.filter(item => eval(condition)); 12

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

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

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

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

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

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

Lhankor_Mhy

2019/09/19 05:36

目的をお伺いした方がいい案件のように思いました。 ・外部入力が挿入される形で条件式文字列を生成するなら、論外です。 ・メンテナンスをしやすくするため、ならば、直接ソースコードを触った方がいいでしょう。 ・サーバが条件式文字列を生成する、ということであれば、外部JSにして読み込んだ方が無難でしょう。
Pltcpx

2019/09/19 05:51

ありがとうございます。 Vue.jsの練習で作っていました。 絞り込みのためのチェックボックスのチェックの変動で条件文を変更したかったです。チェックボックスが増えるたびに、ベタな条件をふやすのはどうかと思い動的に条件をつくることを意図しています。
Lhankor_Mhy

2019/09/19 06:02

補足ありがとうございます。 質問に追記された方が、目的に合う回答がつきやすそうな気がします。
Pltcpx

2019/09/19 06:05

追記しました。ありがとうございます。
guest

回答2

0

ベストアンサー

コールバック関数を用意するだけでは?

javascript

1let products = [ 2 {name:"iphone11Pro", price:100000, delv:0, isSale:false, isUsed: false}, 3 {name:"iphone11", price:90000, delv:0, isSale:false, isUsed: false}, 4 {name:"iphoneXS", price:80000, delv:0, isSale:false, isUsed: false}, 5 {name:"iphoneXR", price:80000, delv:0, isSale:true, isUsed: false}, 6 {name:"iphone8", price:70000, delv:500, isSale:true, isUsed: false}, 7 {name:"iphone7", price:60000, delv:500, isSale:true, isUsed: true}, 8 {name:"iphoneSE", price:50000, delv:0, isSale:true, isUsed: true}, 9]; 10 11const callback=item=>item.delv > 0 && item.isSale == true && item.isUsed == true; 12products=products.filter(item=>callback(item)); 13console.log(products);

投稿2019/09/19 05:23

編集2019/09/19 05:24
yambejp

総合スコア114837

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

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

yambejp

2019/09/19 05:32

evalは技術的にいきづまったときの最後の手段なので この程度の処理に適用するのはやめたほうがいい
Pltcpx

2019/09/19 05:58

ありがとうございます。evalはいかがなものかと思って質問しました。 画面側でリストの絞り込みチェックボックスがいくつもあって、そのチェック状況でフィルタ条件を動的に変更するのを意図していましたので、ベタ書きしない方法を探しています。
yambejp

2019/09/19 06:02

コールバックを複数用意して配列に入れておくか、switchで振り分ければよいかと
Pltcpx

2019/09/19 06:10

なるほど、まとめかたの参考になりました。ありがとうございます。
Pltcpx

2019/09/19 06:28

あー、AND条件なので、配列にいれて複数回該当するフィルタを実行すればいいってことですかね・・・。それで試してみますねー。
guest

0

質問主です。以下でいただいたコメントを参考にこうしました。
AND条件なので、配列に条件コールバックをいれてfor文で回して複数回filterかけるようにしました。

JavaScript

1 2//チェックボックスに対応する個々のCallbackを作っておき、 3//条件に応じて、条件文コールバックの配列詰め合わせを作成 4 5let callbacksArray = getCallbacks(); 6 7//中身 8//[item => item.isSale == true, item => item.delv == 0, item => item.isUsed == true] 9 10//コールバック詰め合わせぶんだけループしてフィルタ 11let newList = this.products; 12 13for (let i = 0; i < callbacksArray.length; i++) { 14 15 newList = newList.filter(item => callbacksArray[i](item)); 16} 17

ありがとうございました。

投稿2019/09/19 07:06

編集2019/09/19 07:15
Pltcpx

総合スコア7

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問