Matching elements from two arrays in javascript - javascript

I am trying to make a small random quizz generator, first array has the questions and they are randomly displayed (when page is loaded or when page is refreshed), the second array has the answers.
Now, when the user typed an answer, if that answer is from the answers' array is shown the correct message, even if it is not correct one for that question, and if the answer is not from the answers' array, the not correct message is shown.
I need a code to solve this (I can do it in if...else and with || and && operators, but for more than 5 entries code becomes too long and too hard to maintain)
Below javascript and html codes
//reload whole page
function refreshMe() {
window.location='index.html';
}
const myQs = [
"How many sides has a hexagon", // must always be the first answer from myRs array
"A circle has...degrees?", // must always be the second answer from myRs array
"2^3=...?",
"2+2:2=..?",
"A triangle has....degrees?",
"Square root of 2 is...?" // to be extend up to 500 entries
];
let randomItem = myQs[Math.floor(Math.random()*myQs.length)];
document.getElementById("demo").innerHTML = randomItem;
function userAnswer() {
const check = document.getElementById('answer').value;
const myRs = [
"6",
"360",
"8",
"3",
"180",
"1.41"
];
// the difference between 0 and -1?
if (myRs.indexOf(check) > -1) {
sayMessage = check + " is the correct answer!";
} else {
sayMessage = check + " is not the correct answer....";
}
document.getElementById("userA").innerHTML = sayMessage;
};
For a random question, now every answer is correct, if a answer out of myRs is typed, the message is not correct. I need a code so that the questions from myQs array to match with its own answer from myRs array, the same index in arrays, first question has first answer, and so on.
I can do it with if...else and || and && operators, but for more than 5 entries the code get too long and too hard for maintaining it.
<p> The question of the moment...</p>
<p id="demo"></p>
<button onclick="refreshMe()">Next one </button><br><br>
<input name="answer" type="text" placeholder="Your answer is....." id="answer">
<br><br>
<button onclick="userAnswer()">Check answer</button>
<p id="userA"></p>

Right now you have two lists. One contains questions, the other answers:
var questions = [ "2 + 2", "2 + 1", "1 + 1" ];
var answers = [ "4", "3", "2" ];
In order to easily check your user input, it's a good idea to convert this data structure to an object in which the question is the key, and the answer the value.
Note that this requires your question and answer combinations to be unique. I.e.: a question can not have multiple answers
var questionsWithAnswers = {
"2 + 2": "4",
// etc.
}
You can convert the data in javascript, so you don't have to rewrite the lists:
var questionsWithAnswers = {};
for (let i = 0; i < questions.length; i += 1) {
questionsWithAnswers[question[i]] = answers[i];
}
Now, your check for a question is:
var answerIsCorrect = questionsWithAnswers[question] === userInput;

I'd recommend revising the schema of your questions.
Housing questions and answers together within objects would probably be the least error prone approach.
See below for a practical example.
// Questions.
const questions = [
{q: 'How may sidea has a hexagon', a: 6},
{q: 'A circle has...degrees?', a: 360},
{q: '2^3=...?', a: 8},
{q: '2+2:2=..?', a: 3},
{q: 'A triangle has....degrees?', a: 180},
{q: 'Square root of 2 is...?', a: 1.41}
]
// Selected.
const selected = questions[Math.floor(Math.random()*questions.length)]
// Question.
const question = selected.q
document.getElementById('question').innerHTML = question
// Normalise.
const normalise = (number) => Math.round(parseFloat(number), 2)
// Submit Answer.
document.getElementById('form').addEventListener('submit', (event) => {
event.preventDefault()
const userAnswer = normalise(document.getElementById('answer').value)
const actualAnswer = normalise(selected.a)
const isCorrect = (userAnswer == actualAnswer)
document.getElementById('feedback').innerHTML = isCorrect && 'Correct 👍' || 'Incorrect 👎'
})
<div><p id="question"></p></div>
<form id="form">
<div><input id="answer" placeholder="Answer .."/></div>
<button>Submit answer</button>
</form>
<div><p id="feedback"></p><div>

First of all, you do understand that having a question and answer available in JS is not a good idea, cause user can see the code.
Anyway, I would combine questions and answer into one structure.
var QAs = [["How many sides has a hexagon", "6"],
["A circle has...degrees?", "360"]]; // and so on
let randomItem = QAs[Math.floor(Math.random()*myQs.length)];
document.getElementById("demo").innerHTML = randomItem[0];
function userAnswer() {
const check = document.getElementById('answer').value;
if (check == randomItem[1]) { // check randomItem availability in this scope. otherwise save to to window.randowItem scope.
sayMessage = check + " is the correct answer!";
} else {
sayMessage = check + " is not the correct answer....";
}
document.getElementById("userA").innerHTML = sayMessage;
}

Related

JavaScript user prompt 2d array lookup - Elf Name Generator

Started with what I thought was a simple idea for a class activity for our JavaScript unit, but falling foul best way to read a JavaScript 2D array based on a user input.
How can I get it to look up the users entry in the first index of the array and output the value in the second index? I need to tell it at some point which index to read and which to output, via similar syntax to [0][1] I imagine, but trial and error is getting me far.
Perhaps there is a better way??
Here is what I have so far, which just outputs the first array entry in its entirety - "A","Angelic"
var firstNames = [
["A","Angelic"],
["B","Blustery"],
........
["Y","Cheery"],
["Z","Dancy"]
];
var firstInitial = window.prompt("What is the first letter of your first name: ").toUpperCase();
let elfFirstName = firstNames.find(firstSearch);
function firstSearch(firstInitial) {
return firstInitial;
}
window.alert("Your Elf Name is " + elfFirstName);
</script>```
Thanks
You could take an object with the initials as keys.
const
firstNames = {
A: "Angelic",
B: "Blustery",
Y: "Cheery",
Z: "Dancy"
},
firstInitial = window.prompt("What is the first letter of your first name: ")[0].toUpperCase(),
elfFirstName = firstNames[firstInitial];
console.log("Your Elf Name is " + elfFirstName);
You do not use find right. It needs to look at the first index of your array that is passed in.
function firstSearch(item) {
return item[0] === firstInitial;
}
So
var firstNames = [
["A", "Angelic"],
["B", "Blustery"],
["Y", "Cheery"],
["Z", "Dancy"]
];
var firstInitial = window.prompt("What is the first letter of your first name: ").toUpperCase();
const elfFirstName = firstNames.find(firstSearch)[1];
function firstSearch(item) {
return item[0] === firstInitial;
}
window.alert("Your Elf Name is " + elfFirstName);
Better solution as I pointed out in the comments is using an array
var firstNames = {
A: "Angelic",
B: "Blustery",
Y: "Cheery",
Z: "Dancy"
};
var firstInitial = window.prompt("What is the first letter of your first name: ").toUpperCase();
const elfFirstName = firstNames[firstInitial];
window.alert("Your Elf Name is " + elfFirstName);

The random question generator is only prompting 1 question in the array of objects, and exiting the prompt. Instead prompting all the questions

I created an array of objects, and it randomly picks a question out of 1 of the objects and puts in in a prompt box.
But, its only prompting 1 question, and it breaks out the prompt box. It doesn't prompt all the other questions 1 after another.
let theQuestions = [
{
question: "What is the capital of Georgia?",
answer: "atlanta"
},
{
question: "What is the name of the Atlanta Baseball Team?",
answer: "atlanta braves"
},
{
question: "How many rings have the Atlanta Falcons Won?",
answer: 0
},
{
question: "What is the name of the NBA team in Miami?",
answer: "miami heat"
}
];// theQuestions array
const randomQuestions = ()=>{
const random = Math.floor(Math.random() *theQuestions.length);
return theQuestions[random];
}// randomQuestions
let question = randomQuestions().question;
let answer = randomQuestions().answer;
const askQuestions = prompt(question);
If you want to ask all questions in a row you need some kind of loop.
Here is an example with a while loop.
This piece in you code wont work anyway because you wont get the right answer most of the times:
let question = randomQuestions().question;
let answer = randomQuestions().answer;
If you wan't to ask the questions in a random order you need an indicator which question was already asked. A simple idea is to just remove the asked question from the array.
let theQuestions = [
{ question: "What is the capital of Georgia?", answer: "atlanta" },
{ question: "What is the name of the Atlanta Baseball Team?", answer: "atlanta braves" },
{ question: "How many rings have the Atlanta Falcons Won?", answer: 0 },
{ question: "What is the name of the NBA team in Miami?", answer: "miami heat" }
];
const randomQuestions = () => {
const index = Math.floor(Math.random() * theQuestions.length);
const question = theQuestions.splice(index, 1);
return question[0];
}
while(theQuestions.length) {
const question = randomQuestions();
const askedQuestion = prompt(question.question);
if (askedQuestion === null) {
console.log("User clicked cancel");
} else {
console.log(askedQuestion.toLowerCase() === question.answer);
}
}

How to use javascript filter() to find the all the same grades and save them into another array, to later printing out the names of the students

I am trying to learn how to use filter() using javascript with strings. My idea is to use filter() to find all occurrences that has the same string value in an array and and use those that to print out all the names that has the same grade from another array.
But I have this far only been able to print all the student's name with the respectively grade instead of for example only all names who has grade 'C'.
What I have tried this far is to input the value/grade into a textbox so I should can use that values to be searched for in the array. I have implemented a basic code that should be able to solve my the mission of this code. But nothing happens unless I use a for loop, then it prints all names with their respectively grade. And as far as I have understood from what I have been reading I should not need to use any for loop to get the code to do what I want.
I am feeling stuck.
I assume that it depends on that I have not been able find any examples that uses strings that must much as all I have found this far is example that uses checks string values after their length and not for the conditions I want to make the code for.
I might have missed the information I need, but This far I have not seen anything close to what might help me understand how to solve this problem.
this is the style of information of some source that I have found and everything else I found this far has been very similar to these.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://www.geeksforgeeks.org/javascript-array-filter
https://www.javascripttutorial.net/javascript-array-filter/
I am not sure if I should show any code or not but here it goes anyway.
var studentArray = ["Clara", "Andreas", "Emilio", "Sarah", "Alice", "Victoria", "Thomas", "Roberta"];
var gradeArray = ["A", "B", "C", "A", "D", "C", "E", "E"];
function input() {
var grade = document.getElementById("grade").value;
return grade;
}
function getGradesToNames() {
var filteredArray = gradeArray.filter(input);
for (var i = 0; i < filteredArray.length; i++){
document.getElementById("output2").innerHTML += studentArray[i] + " " + filteredArray[i] + "<br/>";
}
}
function print() {
input();
getGradesToNames();
}
I know I am a complete beginner but I hope someone can help me by guiding me in the right direction.
Thank you in advance.
Using .filter won't work well here, at least not alone, because once you've filtered one of the arrays, you'll have lost the index of each item that connects it to the item in the other array. If you want to filter, zip the arrays together first, so you have an array of objects with name and grade properties:
var studentArray = ["Clara", "Andreas", "Emilio", "Sarah", "Alice", "Victoria", "Thomas", "Roberta"];
var gradeArray = ["A", "B", "C", "A", "D", "C", "E", "E"];
const zipped = studentArray.map((name, i) => ({ name, grade: gradeArray[i] }));
function getGradesToNames() {
zipped
.filter(({ grade }) => grade === 'C')
.forEach(({ name, grade }) => {
document.getElementById("output2").innerHTML += name + " " + grade + "<br/>";
});
}
getGradesToNames();
<div id="output2"></div>
If the grade to be searched for comes from a variable, like an input, just substitute the === 'C' with a comparison against that variable.

how to find identical strings in a array of place names from a survey (using javascript)

This is my first time on here, so forgive me if the answer to this is obvious - but can't find a possible solution anywhere.
I'm trying to pull numbers out of a survey I want to set up, which will generate a list of cities. Thus:
var cities = array ['city1', 'city2', 'city3', 'city2', 'city4', 'city1', city2'];
Will generate a list: city1: 2, city2: 3, city3: 1, city4: 1
Is there a way to go through an array like this in Javascript? The cities will not be pre-determined - ie people could be entering anything.
Thanks in advance for any help you can give me.
tim
Like Niet already answered:
You go through the list and put the keys into a object and increment the values.
var generatedList = {};
for(var i=0;i<cities.length;i++){
if(generatedList[cities[i]]){
generatedList[cities[i]]++;
}else{
generatedList[cities[i]] = 1;
}
}
The answer is "obvious"... if you know where to start. So here's the starting line:
Create an object (literal, {})
Iterate through the array. For each item:
If the item doesn't exist as a key of the object, create the key with value 0
Increment the key on the object by 1
And... done! That's all there is to it.
This has been answered since I started this demo but this should help you understand what's happening. Open this demo with the developer console open to view the output:
http://jsfiddle.net/46wnj/
var cities = new Array('city1', 'city2', 'city3', 'city2', 'city4', 'city1', 'city2');
var citiesObject = {};
for (var x = 0; x < cities.length; x++)
{
if (citiesObject[cities[x]])
{
citiesObject[cities[x]]++
}
else
{
citiesObject[cities[x]] = 1;
}
}

People guesser program with JavaScript objects

I'm trying to learn JavaScript, and so I'm doing this project to practice. I'm trying to figure out how the objects and all that work. Basically what I want, is a list of people, as objects, with certain properties assigned to each. Then it to ask a bunch of questions until it guesses the person you're thinking of. I've searched around, but can't really find exactly how to do this. This is what I have so far:
function person(name,age,eyecolor,gender,eyeglasses)
{
this.name=name;
this.age=age;
this.eyecolor=eyecolor;
this.gender=gender;
this.eyeglasses=eyeglasses;
}
var Dad=new person("Dad",45,"blue","male",true);
var Mom=new person("Mom",48,"blue","female",false);
var Brother=new person("Brother",16,"blue","male",false);
var Sister=new person("Sister",15,"green","female",false);
function askQuestion (){
}
function begin(){
askQuestion();
}
Now what I want is a way that I can, in the askQuestion function, select a question from a list based on what we know so far about the person. And then recalculate who of the people it could be, and then pick another question to ask, until we know who it is. Hopefully I've made this clear. How would I do that?
This is a bit like the game "Guess Who?" no? Alright so this is what you do:
First you create a constructor for a person. You got this right.
function Person(name, age, eyecolor, gender, eyeglasses) {
this.name = name;
this.age = age;
this.eyecolor = eyecolor;
this.gender = gender;
this.eyeglasses = eyeglasses;
}
Then you create list of possible people. A list means an array.
var people = [
new Person("Dad", 45, "blue", "male", true),
new Person("Mom", 48, "blue", "female", false),
new Person("Brother", 16, "blue", "male", false),
new Person("Sister", 15, "green", "female", false)
];
Then you keep asking questions to guess who the person is. To keep asking means to use a loop. We'll keep looping until there's only one person left in the list (the person we're looking for):
while (people.length > 1) askQuestion();
Next we define the askQuestion function. First we need to select what question to ask. So we make a list of questions. Again this is an array. We'll also store which property to test and the result for true and false conditions.
var questions = [
["eyecolor", "blue", "green", "Does the person have blue eyes?"],
["gender", "male", "female", "Is the person a male?"],
["eyeglasses", true, false, "Does the person wear eyeglasses?"]
];
These three questions are all you need to know to determine who the person is. Next we record which question is currently being asked (0, 1 or 2).
var question_no = 0;
Finally we ask the questions to determine who the person is:
function askQuestion() {
var question = questions[question_no++];
var answer = confirm(question[3]) ? question[1] : question[2];
var predicate = question[0];
people = people.filter(function (person) {
return person[predicate] === answer;
});
}
Here we ask the user a question, determine which answer he chose and use that information to filter the people who match the given description. Finally we end up with one person:
alert("The person you're thinking about is " + people[0].name + ".");
See the working demo here: http://jsfiddle.net/9g6XU/
Here's how I would do it. It's shorter than Aadit's answer, and in my opinion, simpler and easier to understand.
Make a list of the people. Use an array literal:
var people = [Dad, Mom, Brother, Sister];
I like to structure my code, so I would put the questions in an object:
var questions = {
"Are they male or female?" : 'gender',
"What is their eye color?" : 'eyecolor',
"Do they wear glasses?" : 'eyeglasses'
};
This could be expanded with as many properties as you want.
Then:
for (question in questions) { //This is how you loop through an object
var property = questions[question]; //This gets the second part of the object property, e.g. 'gender'
var answer = prompt(question);
//filter is an array method that removes items from the array when the function returns false.
//Object properties can be referenced with square brackets rather than periods. This means that it can work when the property name (such as 'gender') is saved as a string.
people = people.filter(function(person) { return person[property] == answer });
if (people.length == 1) {
alert("The person you are thinking of is " + people[0].name);
break;
}
if (people.length == 0) {
alert("There are no more people in the list :(");
break;
}
}
And I, too, made you a fiddle.Here it is.

Categories