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

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

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

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

checkbox

checkboxは、GUIのエレメントです。また、HTML<input>タグのtype属性で扱われる値を指します。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

2回答

1998閲覧

配列の出現回数によるフィルター方法を教えてください

yuu12345678

総合スコア12

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

checkbox

checkboxは、GUIのエレメントです。また、HTML<input>タグのtype属性で扱われる値を指します。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2019/07/15 18:45

複数ランダムにのa・b・c・d・eクラスを持つチェックボックスをユーザーが選択したときに
3以上同じ英語のクラスにチェックが入ったときに
下にある非表示にしたボタンの同じ英語のボタンだけを表示させたいです
1つのチェックの時は表示させたくないです

配列で出現回数は取得できたのですが
data.filter(function(value){ return ( value >= 3);} );
で出現回数が3以上のものをフィルターで抽出したいのですが
上手くできずエラーになってしまいどこがおかしいのか教えていただけないでしょうか・・

html

1<ul> 2 <li class="a d e b"> 3 <input type="checkbox" name="check" id="label1"> 4 <label for="label1"></label> 5 </li> 6 <li class="b c a"> 7 <input type="checkbox" name="check" id="label1"> 8 <label for="label1"></label> 9 </li> 10 <li class="a d e b c"> 11 <input type="checkbox" name="check" id="label1"> 12 <label for="label1"></label> 13 </li> 14 <li class="d e b c"> 15 <input type="checkbox" name="check" id="label1"> 16 <label for="label1"></label> 17 </li> 18</ul> 19<div class="btnA"></div> 20<div class="btnB"></div> 21<div class="btnC"></div> 22<div class="btnD"></div>

jQuery

1$(function() { 2$('input[name="check"]').change(function() { 3$('button').hide(); 4if ($('input[name="check"]:checked').length >= 3) { 5var _tmp = []; 6$('input[name="check"]:checked').each(function() { 7_tmp.push($(this).parents('li').attr('class').split(' ')); 8}); 9_tmp = Array.prototype.concat.apply([], _tmp); 10 11var data={}; 12for(var i=0;i<_tmp.length;i++){ 13var key=_tmp[i]; 14if(data[key]==undefined) data[key]=0; 15data[key]++; 16} 17 18var showClass = data.filter(function(value){ return ( value >= 3);} ); 19 20 21if (showClass) { 22$('.' + showClass).show(); 23} else { 24$('button').hide(); 25} 26 27}; 28}); 29});

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

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

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

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

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

kei344

2019/07/17 13:56

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

回答2

0

こんにちは

どこがおかしいのか教えていただけないでしょうか・・

ご質問にあるコードで、エラーの起きる原因は以下の行です。

修正前:

javascript

1var showClass = data.filter(function(value){ return ( value >= 3);} );

上記によって、カウントした出現回数が 3 以上のクラス名をfilterを使って抽出したいという意図は分かりますが、filter は配列のメソッドですので、 配列ではない(普通の)オブジェクトである data に対して data.filter(・・・ と書くと、以下のようなエラーメッセージが表示されるものと思います。

data.filter is not a function

filter を使うのであれば、filter する対象が配列になっていなければなりませんので、たとえば以下のようにします。

修正後:

javascript

1var showClasses = Object.entries(data).filter(([_, value]) => value >= 3).map(e => e[0]); 2

上記によって、 showClasses には、カウントした個数が3以上のクラス名の配列(例: ["b", "d"]) が入ってきます。

以下に、上記の修正を含め、適宜スタイルを追加したりしたものを以下に上げておきましたので、参考にしてみてください。

いくつかの修正を経たHTMLは以下です。

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Q200759</title> 6 <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> 7 <script> 8 $(function() { 9 $('input[name="check"]').change(function() { 10 $('button').hide(); 11 if ($('input[name="check"]:checked').length >= 3) { 12 var _tmp = []; 13 $('input[name="check"]:checked').each(function() { 14 _tmp.push($(this).parents('li').attr('class').split(' ')); 15 }); 16 17 _tmp = Array.prototype.concat.apply([], _tmp); 18 19 var data={}; 20 for(var i=0;i<_tmp.length;i++){ 21 var key=_tmp[i]; 22 if(data[key]==undefined) data[key]=0; 23 data[key]++; 24 } 25 26 var showClasses = Object.entries(data).filter(([_, value]) => value >= 3).map(e => e[0]); 27 28 $('.button').hide(); 29 showClasses.forEach(clazz => { 30 $(`.button.${clazz}`).show(); 31 }); 32 }; 33 }); 34 }); 35 </script> 36 <style> 37 .button { 38 width: 80px; 39 height: 80px; 40 font-size: 40pt; 41 color: white; 42 text-align: center; 43 float: left; 44 margin-right: 10px; 45 } 46 .button.a { background-color: red; } 47 .button.b { background-color: green; } 48 .button.c { background-color: blue; } 49 .button.d { background-color: orange; } 50 ul { list-style: none; } 51 li { font-size: 16pt; } 52 label { padding-bottom: 5px; } 53 input[type=checkbox] { transform: scale(2); vertical-align: middle; } 54 </style> 55</head> 56<body> 57<ul> 58 <li class="a d e b"> 59 <input type="checkbox" name="check" id="checkbox1"> 60 <label for="checkbox1">a d e b</label> 61 </li> 62 <li class="b c a"> 63 <input type="checkbox" name="check" id="checkbox2"> 64 <label for="checkbox2">b c a</label> 65 </li> 66 <li class="a d e b c"> 67 <input type="checkbox" name="check" id="checkbox3"> 68 <label for="checkbox3">a d e b c</label> 69 </li> 70 <li class="d e b c"> 71 <input type="checkbox" name="check" id="checkbox4"> 72 <label for="checkbox4">d e b c</label> 73 </li> 74</ul> 75<div class="button a">A</div> 76<div class="button b">B</div> 77<div class="button c">C</div> 78<div class="button d">D</div> 79</body> 80</html>

何か意図通りのものになっていない箇所があればコメントからお知らせください。

補足

上記に挙げたHTMLに含まれるJavaScript のコードを、自分だったらさらにこのように短くしてしていくと思います、という修正案を以下に追記します。

まず、 _tmp は、こんな風にも作れます。

javascript

1const checkedBoxes = $('input[name="check"]:checked'); 2 3if (checkedBoxes.length >= 3) { 4 const _tmp = checkedBoxes.toArray().reduce((ary, e) => 5 [...ary, ...e.parentNode.classList], []);

次に、

  • _tmp に出現する異なる要素をプロパティとし、各々の個数を値とするオブジェクトを作ること
  • このオブジェクトのプロパティと値の組の中で、値が3以上であるもののみを持つオブジェクトを作ること

という2つのステップを行うために、Lodash という便利なライブラリが提供してくれているメソッドを使います。

まず、 _tmp に出現する異なる要素をプロパティとし、各々の個数を値とするオブジェクトは以下で得られます。

javascript

1const counts = _.countBy(_tmp);

上記で得られた counts の中で個数が3以上のものだけをピックアップしたオブジェクトは以下で得られます。

javascript

1const countsGte3 = _.pickBy(counts, v => v >= 3);

上記で得られた、 countsGte3 を使って、 .show()を適用する複数のボタンを取得するセレクタを作ります。

javascript

1const buttonsSelectorToShow = Object.keys(countsGte3).map(x => `.button.${x}`).join(',');

上記で得られた、 buttonsSelectorToShow を使って、以下にて、該当のボタンにまとめて .show()を適用できます。

javascript

1$(buttonsSelectorToShow).show()

回答のコードを上げたレポジトリで、上記の修正をした後のHTMLは以下です。(初期表示と、チェックボックスが変更されたとき、いったん全てのボタンを隠すようにしています)

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Q200759</title> 6 <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> 7 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.14/lodash.min.js"></script> 8 <script> 9 $(function() { 10 $('.button').hide(); 11 12 $('input[name="check"]').change(function() { 13 $('.button').hide(); 14 15 // チェックされているボックスを取得します。 16 const checkedBoxes = $('input[name="check"]:checked'); 17 18 if (checkedBoxes.length >= 3) { 19 20 // _tmpは、こんな風にも作れます。 21 const _tmp = checkedBoxes.toArray().reduce((ary, e) => 22 [...ary, ...e.parentNode.classList], []) 23 24 // _tmp に出現する異なる要素をプロパティとし、各々の個数を値とするオブジェクトは以下で得られます。 25 const counts = _.countBy(_tmp); 26 27 // counts の中で個数が3以上のものだけをピックアップしたオブジェクトは以下で得られます。 28 const countsGte3 = _.pickBy(counts, v => v >= 3); 29 30 // show()を適用するボタンのセレクタを作成します。 31 const buttonsSelectorToShow = Object.keys(countsGte3).map(x => `.button.${x}`).join(','); 32 33 // 上記のセレクタを使って、show()を適用します。 34 $(buttonsSelectorToShow).show() 35 36 }; 37 }); 38 }); 39 </script> 40 <style> 41 .button { 42 width: 80px; 43 height: 80px; 44 font-size: 40pt; 45 color: white; 46 text-align: center; 47 float: left; 48 margin-right: 10px; 49 } 50 .button.a { background-color: red; } 51 .button.b { background-color: green; } 52 .button.c { background-color: blue; } 53 .button.d { background-color: orange; } 54 ul { list-style: none; } 55 li { font-size: 16pt; } 56 label { padding-bottom: 5px; } 57 input[type=checkbox] { transform: scale(2); vertical-align: middle; } 58 </style> 59</head> 60<body> 61<ul> 62 <li class="a d e b"> 63 <input type="checkbox" name="check" id="checkbox1"> 64 <label for="checkbox1">a d e b</label> 65 </li> 66 <li class="b c a"> 67 <input type="checkbox" name="check" id="checkbox2"> 68 <label for="checkbox2">b c a</label> 69 </li> 70 <li class="a d e b c"> 71 <input type="checkbox" name="check" id="checkbox3"> 72 <label for="checkbox3">a d e b c</label> 73 </li> 74 <li class="d e b c"> 75 <input type="checkbox" name="check" id="checkbox4"> 76 <label for="checkbox4">d e b c</label> 77 </li> 78</ul> 79<div class="button a">A</div> 80<div class="button b">B</div> 81<div class="button c">C</div> 82<div class="button d">D</div> 83</body> 84</html>

ご質問の本題からはだいぶ離れた、応用編になってしまったかもしれませんが、Lodash はちょっとずつでも使い始めてみると、とても役に立つことがあるので、そのご紹介でした。

以上、参考になれば幸いです。

投稿2019/07/15 21:40

編集2019/07/16 14:47
jun68ykt

総合スコア9058

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

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

yuu12345678

2019/07/16 12:24

ありがとうございます! 配列になっていなかったのがエラーの原因だったんですね! わかりやすく説明していただき助かります!
jun68ykt

2019/07/16 14:42

どういたしまして。原因が把握できれば何よりです。 補足として、Lodash という便利なライブラリを使ったりしてリファクタしたコード案を、回答のほうに追記しましたので、参考にして頂ければと思います。
guest

0

HTMLがおかしいですが、調整していいならこんな感じ

javascript

1<script> 2$(function(){ 3 $('.btn').hide(); 4 $('ul :checkbox').on('change',function(){ 5 $.each([".a",".b",".c",".d"],function(x,y){ 6 $('.btn').filter(y).toggle($(y).has(':checked').length>=3); 7 }); 8 }); 9}); 10</script> 11<ul> 12 <li class="a d e b"> 13 <label><input type="checkbox" name="check">adeb</label> 14 </li> 15 <li class="b c a"> 16 <label><input type="checkbox" name="check">bca</label> 17 </li> 18 <li class="a d e b c"> 19 <label><input type="checkbox" name="check">adebc</label> 20 </li> 21 <li class="d e b c"> 22 <label><input type="checkbox" name="check">debc</label> 23 </li> 24</ul> 25<div class="btn a">A</div> 26<div class="btn b">B</div> 27<div class="btn c">C</div> 28<div class="btn d">D</div>

投稿2019/07/16 00:37

yambejp

総合スコア114769

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

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

yuu12345678

2019/07/16 12:28

ありがとうございます! すごくスッキリまとめていただきわかりやすくなりすごく助かりました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問