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

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

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

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

1660閲覧

【JavaScript】アキネーターのような「正解絞り込みクイズ」を設計したい!(不要な質問を非表示にする方法編)

KentaroxKondo

総合スコア12

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

1クリップ

投稿2021/05/28 12:52

編集2021/05/29 02:24

正解絞り込みクイズで、尋ねる必要がなくなった質問を非表示にしたい

興味があり、プログラミングの入門としてJavaScriptを勉強し始めた初心者です。
質問に回答するごとに、正解となる選択肢がどんどんと絞り込まれていく、**「アキネーター」**のようなプログラムを作成したいと野望を抱いています!

前回も同様の質問をさせていただき、偉大なる先輩方のアドバイスをいただいた結果、以下のような式にまでたどり着くことができました!

HTML

1<body> 2 3 <div id="Questions"><h1>質問</h1> 4 5 <div id="Q1"> 6 <p>Q. 動物ですか?</p> 7 <label><input type="radio" name="RadGrpA1" id="A1Yes">YES</label> 8 <label><input type="radio" name="RadGrpA1" id="A1No">No</label> 9 <label><input type="radio" name="RadGrpA1">わからない</label> 10 <label style="display: none;"><input type="radio" name="RadGrpA1" checked>未選択</label> 11 </div> 12 13 <div id="Q2"> 14 <p>Q. 首が長いですか?</p> 15 <label><input type="radio" name="RadGrpA2" id="A2Yes">YES</label> 16 <label><input type="radio" name="RadGrpA2" id="A2No">No</label> 17 <label><input type="radio" name="RadGrpA2">わからない</label> 18 <label style="display: none;"><input type="radio" name="RadGrpA2" checked>未選択</label> 19 </div> 20 21 <div id="Q3"> 22 <p>Q. 植物ですか?</p> 23 <label><input type="radio" name="RadGrpA3" id="A3Yes">YES</label> 24 <label><input type="radio" name="RadGrpA3" id="A3No">No</label> 25 <label><input type="radio" name="RadGrpA3">わからない</label> 26 <label style="display: none;"><input type="radio" name="RadGrpA3" checked>未選択</label> 27 </div> 28 29 <div id="Q4"> 30 <p>Q. トゲがありますか?</p> 31 <label><input type="radio" name="RadGrpA4" id="A4Yes">YES</label> 32 <label><input type="radio" name="RadGrpA4" id="A4No">No</label> 33 <label><input type="radio" name="RadGrpA4">わからない</label> 34 <label style="display: none;"><input type="radio" name="RadGrpA4" checked>未選択</label> 35 </div> 36 37 <div id="Q5"> 38 <p>Q. 人間ですか?</p> 39 <label><input type="radio" name="RadGrpA5" id="A5Yes">YES</label> 40 <label><input type="radio" name="RadGrpA5" id="A5No">No</label> 41 <label><input type="radio" name="RadGrpA5">わからない</label> 42 <label style="display: none;"><input type="radio" name="RadGrpA5" checked>未選択</label> 43 </div> 44 45 <div id="Q6"> 46 <p>Q. ミュージシャンですか?</p> 47 <label><input type="radio" name="RadGrpA6" id="A6Yes">YES</label> 48 <label><input type="radio" name="RadGrpA6" id="A6No">No</label> 49 <label><input type="radio" name="RadGrpA6">わからない</label> 50 <label style="display: none;"><input type="radio" name="RadGrpA6" checked>未選択</label> 51 </div> 52 53 </div> 54 55 <h1>可能性</h1> 56 <p id="Cabbage">キャベツ</p> 57 <p id="Cactus">サボテン</p> 58 <p id="Elephant">象</p> 59 <p id="Giraffe">キリン</p> 60 <p id="MichaelJackson">マイケルジャクソン</p> 61 <p id="NobunagaOda">織田信長</p> 62 63</body>

JavaScript

1document.getElementById("Questions").addEventListener("change", () => { 2 3 let Judge = {Cabbage:"", Cactus:"", Elephant:"", Giraffe:"", MichaelJackson:"", NobunagaOda:""}; 4 let JudgeArray = ["Cabbage", "Cactus", "Elephant", "Giraffe", "MichaelJackson", "NobunagaOda"]; 5 6 const ResponseAndProcess = [ 7 {Response:"A1Yes", omit:["Cabbage","Cactus"]}, 8 {Response:"A1No", omit:["Elephant","Giraffe","MichaelJackson","NobunagaOda"]}, 9 {Response:"A2Yes", omit:["Cabbage","Cactus","Elephant","MichaelJackson","NobunagaOda"]}, 10 {Response:"A2No", omit:["Giraffe"]}, 11 {Response:"A3Yes", omit:["Elephant","Giraffe","MichaelJackson","NobunagaOda"]}, 12 {Response:"A3No", omit:["Cabbage","Cactus"]}, 13 {Response:"A4Yes", omit:["Cabbage","Elephant","Giraffe","MichaelJackson","NobunagaOda"]}, 14 {Response:"A4No", omit:["Cactus"]}, 15 {Response:"A5Yes", omit:["Cabbage","Cactus","Elephant","Giraffe"]}, 16 {Response:"A5No", omit:["MichaelJackson","NobunagaOda"]}, 17 {Response:"A6Yes", omit:["Cabbage","Cactus","Elephant","Giraffe","NobunagaOda"]}, 18 {Response:"A6No", omit:["MichaelJackson"]}, 19 ]; 20 21 for (let i=0; i<ResponseAndProcess.length; i++) { 22 if (document.getElementById(ResponseAndProcess[i].Response).checked) { 23 for (let j=0; j<ResponseAndProcess[i].omit.length; j++) { 24 Judge[ResponseAndProcess[i].omit[j]] = "不正解"; 25 } 26 } 27 } 28 29 for (let i = 0; i < JudgeArray.length; i++) { 30 if (Judge[JudgeArray[i]] == "不正解") { 31 document.getElementById(JudgeArray[i]).classList.add("ZeroPossibility"); 32 } else { 33 document.getElementById(JudgeArray[i]).classList.remove("ZeroPossibility"); 34 } 35 } 36 37});

不正解となる回答に「ZeroPossibility」というクラスを付与し、CSS操作でグレーアウトさせる動きです。

ここまでは綺麗に動いてくれたので嬉しいのですが、欲を言うと、「尋ねる必要のなくなった質問」に更にクラス等を付与・非表示にして、回答する手数も最短で正解に辿り着けるような形に仕上げたいです。

例:「動物ですか?」が「はい」なら、「植物ですか?」と「トゲがありますか?」という質問を非表示にさせる。

どの質問から回答しても機能させたいのですが、なかなかスマートな方法を発想できずに難儀しているため、皆さまならどのように上記を実現させるのか、お知恵を拝借したく質問させていただきました。

他力本願で申し訳ございませんが、何卒あたたかくご回答いただけますと幸いですm(_ _)m

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

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

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

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

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

miyabi_takatsuk

2021/05/28 12:56

まず、コードはインデント整備して下さい。 他人が見れるようなコードにならなくなります。
KentaroxKondo

2021/05/28 13:03

申し訳ございません。htmlは最初からインデントできていたのですが、JavaScriptの方は投稿・編集画面ではインデントされているのに、プレビュー画面で左揃えになってしまいます・・・直し方がわからないのですが、ご存知でしたらご教示いただけますでしょうか・・・m(_ _)m
miyabi_takatsuk

2021/05/28 13:04

? 半角スペースで入れればインデントになるかと思いますよ。
KentaroxKondo

2021/05/28 13:25

やはり、JavaScriptの方だけが半角スペースやタブを入れてもプレビューが微動だにしません・・・Enterの改行や文字入力はしっかりと反映するのですが・・・見づらくてご不便をおかけし申し訳ございませんm(_ _)m
Lhankor_Mhy

2021/05/29 01:44

補足願います。 「尋ねる必要のなくなった質問」とは、その質問のある選択肢を選ぶと正解がなくなってしまう質問、という理解でいいですか?
KentaroxKondo

2021/05/29 02:15

>K_3578様 情報提供ありがとうございます。ただ、私の使い方が悪いのか、ツールを使ってもteratailの編集画面にペーストすると、Tabも半角スペースも読み取ってもらえずに左揃えになってしまうようです・・・見づらいコードでご不便をおかけします。
K_3578

2021/05/29 02:20

>質問者さん 原因わかりました。HTMLとJavaScriptのコード間にある無駄なバッククォート3つが悪さしてます。 多分消したらインデントされると思います。
KentaroxKondo

2021/05/29 02:20

>Lhankor_Mhy様 説明がいたらずすみません。 たとえば、「植物ですか?」が「Yes」ならば、もう植物か動物かの切り分けができているので、「動物ですか?」という質問をする価値はありません。それを聞いたところで、更に回答が絞り込まれるわけではないからです。 同様に、「人間ですか?」が「No」ならば、「ミュージシャンですか?」という質問をしても無意味ですね。 こういう、回答の絞り込みや切り分けの観点から、尋ねる必要がなくなった質問を非表示にする機能を実装したいと願っていますm(_ _)m
KentaroxKondo

2021/05/29 02:25

>K_3578様 原因特定、ありがとうございます!まさに仰ったとおりで、バッククオートが通常は3つで囲むべきところ、6つ連続で記載されている箇所がありました。 修正したところ、改善しました。ご指摘いただきありがとうございます。以後気をつけますm(_ _)m
Lhankor_Mhy

2021/05/29 02:26

その「質問をする価値」はどのように算定するのですか? ということをお聞きしています。
Lhankor_Mhy

2021/05/29 02:39

ロジックの提示がわかりにくかったかもしれません。 その質問のいずれかの選択肢を選ぶと正解候補が減らない、という表現ならご納得いただけそうですか? 質問が排中的なので、これは「その質問のいずれかの選択肢を選ぶと正解がなくなってしまう」と等価だと思います。
KentaroxKondo

2021/05/29 02:47

>Lhankor_Mhy様 理解がいたらず申し訳ございません。おっしゃっていただいた通り(?)で、「正解候補が減らない」ような質問は、回答する意義がないので非表示にしたいという考えです。 ーーーーーーーーーーーーーーーーーーーー ちなみに各設問の意図は以下です: Q1は、象、キリン、マイケルジャクソン、織田信長を「不正解」にするかどうかの質問 Q2は、キリンを「不正解」にするかどうかの質問 Q3は、キャベツ、サボテンを「不正解」にするかどうかの質問 Q4は、サボテンを「不正解」にするかどうかの質問 Q5は、マイケルジャクソン、織田信長を「不正解」にするかどうかの質問 Q6は、マイケルジャクソンを「不正解」にするかどうかの質問 ーーーーーーーーーーーーーーーーーーーー すでに、絞り込み・切り分けを狙っている選択肢が「不正解」状態ならば、設問ごと非表示にしたいです。
KentaroxKondo

2021/05/30 14:52

(自分用メモです・・・Lhankor_Mhyさんにいただいた式を頑張って解釈・・・) //セレクタ「Questions」が内包する各「div」要素から「ZeroPossibility」クラスを取り除く。 document.querySelectorAll('#Questions > div').forEach(el => el.classList.remove("ZeroPossibility")) //Object.entries(Judge)で、[[Cabbage, ""], [Cactus, ""], [Elephant, ""], [Giraffe, ""], [MichaelJackson, ""], [NobunagaOda, ""]]という配列を取得する。参照:console.log(Object.entries(Judge)); //flatMap関数により、上記の配列の次元を一つ下げて、次の状態にする:[Cabbage, ""], [Cactus, ""], [Elephant, ""], [Giraffe, ""], [MichaelJackson, ""], [NobunagaOda, ""] //各オブジェクトの[1]番目が"不正解"ならば、オブジェクトを空っぽにする。"不正解"ではない場合は、[0]番目の要素を残して、次のような形式の配列を作る:[Cabbage, Cactus, Elephant, Giraffe, MichaelJackson, NobunagaOda](正解候補の選択肢) //※flat化した状態の配列を確認するには次を参照:console.log(Object.entries(Judge).flat()); ←flatMap関数で取得している配列の状況を確認するためには、flat()を使うと楽。 //※原文に近い形だと、次の式で確認することも可能:console.log(Object.entries(Judge).flatMap(e => e[1] === "不正解" ? e : e)); const Possibilities = Object.entries(Judge).flatMap(e => e[1] === "不正解" ? [] : e[0]); //Possibilitiesで吐き出した正解候補の選択肢がResponseAndProcess>Omit内の候補にひとつも含まれていない場合(※everyは配列が条件すべてを満たす場合にtrueを返す)に、Omitの対となるResponse(例:A1Yes/A1No, etc.)を配列に格納する。条件を満たさない場合は空配列にする。 //参考:console.log(ResponseAndProcess.flat()); const ZeroPossibilityResponses = ResponseAndProcess.flatMap(e => Possibilities.every(x => !e.Omit.includes(x)) ? e.Response : []) ZeroPossibilityResponses.forEach(opt => { const $Options = document.getElementById(opt); //各idの設問が未選択状態なら、その親要素となる(closest)divに「ZeroPossibility」クラスを付与する。 if(!$Options.checked){ $Options.closest('div').classList.add('ZeroPossibility') } });
guest

回答1

0

ベストアンサー

「尋ねる必要のなくなった質問」とは、その質問のいずれかの選択肢を選ぶと正解がなくなってしまう質問のこと、という前提で回答します。

js

1document.querySelectorAll('#Questions > div').forEach(el => el.classList.remove("ZeroPossibility")) 2 3const possibilities = Object.entries(Judge).flatMap(e => e[1] === "不正解" ? [] : e[0]); 4const ZeroPossibilityResponsies = ResponseAndProcess.flatMap(e => possibilities.every(x => e.omit.includes(x)) ? e.Response : []) 5ZeroPossibilityResponsies.forEach(responce => { 6 document.getElementById(responce).closest('div').classList.add('ZeroPossibility') 7});

補足依頼欄の返答を受けて追記

「その質問のいずれかの選択肢を選ぶと正解候補が減らない」というロジックで書いたコードも提示します。
ただ、結果は変わらないと思います。

js

1document.querySelectorAll('#Questions > div').forEach(el => el.classList.remove("ZeroPossibility")) 2 3const possibilities = Object.entries(Judge).flatMap(e => e[1] === "不正解" ? [] : e[0]); 4const ZeroPossibilityResponsies = ResponseAndProcess.flatMap(e => possibilities.every(x => !e.omit.includes(x)) ? e.Response : []) 5ZeroPossibilityResponsies.forEach(responce => { 6 document.getElementById(responce).closest('div').classList.add('ZeroPossibility') 7});

補足依頼欄の返答を受けて追記2

「絞り込み・切り分けを狙っている選択肢が「不正解」状態ならば、設問ごと非表示」というロジックで書いたコードも提示します。
ただ、結果は3つとも同じだと思います。

信用できないのは仕方ないけど、だまされたと思って試してほしい……

js

1document.querySelectorAll('#Questions > div').forEach(el => el.classList.remove("ZeroPossibility")) 2 3const ZeroPossibilities = Object.entries(Judge).flatMap(e => e[1] === "不正解" ? e[0] : []); 4const ZeroPossibilityResponsies = ResponseAndProcess.flatMap(e => e.omit.every(x => ZeroPossibilities.includes(x)) ? e.Response : []) 5ZeroPossibilityResponsies.forEach(responce => { 6 document.getElementById(responce).closest('div').classList.add('ZeroPossibility') 7});

投稿2021/05/29 02:12

編集2021/05/29 02:58
Lhankor_Mhy

総合スコア36960

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

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

KentaroxKondo

2021/05/29 03:04

>Lhankor_Mhy いたらぬ質問にも親切にご回答いただき、ありがとうございます!(それも複数パターンで書いていただけるなんて・・・) 私の未熟な理解では、まだご提示いただいたコードで何が起きているのか完全に理解できませんが、教えていただいた通りコードを記述すると、綺麗に動作していることを確認いたしました! 長時間悩んでいたので、すっきりしました。また、プログラマーさんの才能に脱帽しております。 また、図々しく追加で一点、質問させていただきたいのですが、「あやまって回答してしまった場合」も選択肢を選び直して対応できるように、回答済みの質問は「ZeroPossibility」を付与せずに常に表示状態にさせたいです。 その場合は、どのようにコーディングすれば良いのでしょうか。私の単純な理解では、各設問のYesかNoが選択状態ならば、ZeroPossibilityをremoveする、といった処理を思いつきましたが、シンプルに記述する方法がひらめかないです・・・
KentaroxKondo

2021/05/30 14:47

>Lhankor_Mhy様 indeterminateの活用方法を理解することが難しかったのですが、いただいた式の途中にif文を追記することで回避することができたようです。非常に助かりました。ありがとうございます! また、ご回答もじっくりと勉強させていただき、処理の意味を理解することができました。まだ活用することは難しそうですが、いつかLhankor_Mhyさんのような視点を持てるようになりたいと、モチベーションが与えられました! 本件に関連して、新たな悩みごとができたので、もしもおよろしければ以下もお助けいただけると嬉しいです・・・ 【JavaScript】1回押す度に、直前に選択したラジオボタンのチェックを解除する「やり直し」ボタンを実装したい!:https://teratail.com/questions/341258?modal=q-comp
Lhankor_Mhy

2021/05/31 01:28

お役に立てたようで何よりです。失礼ながら、あれが読み解けるとは思っていませんでしたので、びっくりしています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問