retrieve elements from two-dimensional array - javascript

I have a quiz with 3-4 answer choices.
How can I retrieve them if the answer choices varies per question ?
I know code if I have the same number of choices for every question.
My code:
var answerArray = [
["black", "green", "yellow", "orange"],
["big","small","long"],
];
function wait() {
questionCounter < 1 ?
(questionCounter++,
generateQuestions(),
};
function generateQuestions() {
gameHTML = "<p class='text-center'>" + questionArray [questionCounter] + "</p><p class='first-answer answer'>A. " + answerArray[questionCounter][0] + "</p><p class='answer'>B. "+answerArray[questionCounter][1]+"</p><p class='answer'>C. "+answerArray[questionCounter][2]+"</p><p class='answer'>D. "+answerArray[questionCounter][3]+"</p>";
$("#mainArea").html(gameHTML);
};

You need to check the length of the answers array for that question and iterate over each answer:
function generateQuestions() {
const letters = ['A', 'B', 'C', 'D', 'E', 'F'];
let gameHTML = "<p class='text-center'>;
// iterate over each answer:
answerArray[questionCounter].forEach((answer, index) => {
const letter = letters[index] + '.';
gameHTML += "<p class='answer'>" + letter + answer + "</p>"
})
$("#mainArea").html(gameHTML);
};

You should probably be using a loop for this even when you know the number, just to make the code more maintainable (like, so you don't have to rewrite the logic in case the number changes.)
For example, you could dynamically make a list of questions like this:
const questionsArray = [
["What's my favorite color?"],
["Describe my favorite toy."]
];
const mainContainer = document.querySelector("#mainContainer");
for(let i = 0; i < questionsArray.length; i++){
// Makes a node to hold the question text
let qTextNode = document.createTextNode(questionsArray[i]);
// Makes a paragraph element to display the question text in
let qParagraph = document.createElement("p");
// Makes a div element to hold this question and all its possible answers
let qContainer = document.createElement("div");
// Gives the container some distinguishing attributes
qContainer.classList.add("question");
qContainer.id = (i + 1);
// Puts the text in the paragraph
qParagraph.appendChild(qTextNode);
// Puts the paragraph in the container
qContainer.appendChild(qParagraph);
// Adds the container (and everything inside it) to the page
mainContainer.appendChild(qContainer);
}
// Prints out the HTML we just created
console.log(mainContainer.outerHTML.split("><").join(">\n<"));
<div id="mainContainer"></div>
It may not look like much when you run the snippet, but as you can see in the console, you now have an organized structure for all your answer choices to live in. Later javascript code can come along and find specific elements on your page, as can CSS styles.
Here's a juiced-up version that adds the answer text for each question. For this, we need a loop inside a loop (since each question has several answer choices that we want to add dynamically):
const questionsArray = [
["What's my favorite color?"],
["Describe my favorite toy."]
];
const answersArray = [
["black", "green", "yellow", "orange"],
["big","small","long"],
];
// Stuff you saw in the previous snippet
const mainContainer = document.querySelector("#mainContainer");
for(let i = 0; i < questionsArray.length; i++){
let qTextNode = document.createTextNode(questionsArray[i]);
let qParagraph = document.createElement("p");
let qContainer = document.createElement("div");
qContainer.classList.add("question");
qContainer.id = (i + 1);
qParagraph.appendChild(qTextNode);
qContainer.appendChild(qParagraph);
// Makes an "ordered list" element to hold the choices
let aList = document.createElement("ol");
// Letters array will be used for item IDs
let letters = "A,B,C,D,E,F,G,H,I,J".split(",");
// A nested loop to add the choices
for(let j = 0; j < answersArray[i].length; j++){
// Makes a textNode to hold the current choice
let aTextNode = document.createTextNode(answersArray[i][j]);
// Makes a list-item element to display the choice text in
let aItem = document.createElement("li");
// Gives the item an id using question number & answer letter
aItem.id = (i + 1) + letters[j];
// Puts the choice text in the item
aItem.appendChild(aTextNode);
// Puts the item in the list
aList.appendChild(aItem);
}
// Done looping through choices, this adds the list to the question container
qContainer.appendChild(aList);
// And... we're back to stuff from the previous snippet
mainContainer.appendChild(qContainer);
}
console.log(mainContainer.outerHTML.split("><").join(">\n<"));
/* The visible letters for the list items come from here, not from the script */
ol{ list-style-type: upper-alpha; }
.question{ margin-top: 25px; }
<div id="mainContainer"></div>

Related

empty array with loop with if statement

I'm trying to do the following and coming across some issues:
create an empty array
Push 2 variables into the empty array
Create a for loop that goes through the two variables
Write an if/elseif statement within the for loop:
Here's my code now:
var numberArray = [ ];{
numberArray.push("age", "phoneNumber");
for(var i=0; i<numberArray.length; i++) {
if(numberArray[i] <=100)
document.getElementById("age").innerHTML = "Age:" + "Age";
else if(numberArray[i]>100)
document.getElementById("phoneNumber").innerHTML = "Phone Number:" + "phoneNumber";
Problems:
you did not show us the HTML, so I will have to assume that the way you worked with the HTML is correct
you push into the array strings instead of variables, which clearly breaches the specification
you try to call push with two values you intend to push
you try to identify the elements based on their length, which might work in this trivial example, but will fail miserably in real-world work, when you have a lot of fields and the length of a number will not uniquely identify its business logic
var numberArray = [ ];
var age = 95;
var phoneNumber = 123;
numberArray.push({name: 'age', value: age}, {name: 'phoneNumber', value: phoneNumber});
for(var i=0; i<numberArray.length; i++) {
if(numberArray[i].name === 'age')
document.getElementById("age").innerHTML = "Age:" + "Age";
else if(numberArray[i].name === 'phoneNumber')
document.getElementById("phoneNumber").innerHTML = "Phone Number:" + "phoneNumber";
}

How to check if data being added to an array already exists in a different array?

I am looking to create a simple script for a Google sheet in which array 1 will already be populated with a list of names. As a new name gets added to array 2, array 1 is checked for the name. If the name which was entered into array 2 is present in array 1 an action will be performed. This search function must take place each time a new name is added to array 2 to determine if it exists in array 1.
function findPlayer() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var picksRange = ss.getRange("B2:M15");
var poolRange = ss.getRange("B21:G96");
var picksPlayerName = picksRange.getValues();
var poolPlayerName = poolRange.getValues();
for (var i = 0; i < picksRange.length; i++)
for (var j = 0; j < poolRange.lenth; j++)
if (picksPlayerName[i] == poolPlayerName[j]) {
poolPlayerName[i].setBackground("red")}
else {
poolPlayerName[j].setBackground("blue");}
}
This is not a complete answer, nor does it perfectly fit your use-case, but you should be able to take it from here, or perhaps come back with another question when you have a question about a specific part of your code.
const existingNames = ["Carl", "Emma", "Sarah", "Ahmad"];
const newNames = ["Emma", "Sarah", "Isa", "Igor", "Kent"];
// go through the new names and check against existing ones
newNames.forEach(newName => {
if(existingNames.includes(newName)) {
// handle duplicates: do nothing?
} else {
// handle new names: maybe add them to the existing names?
existingNames.push(newName);
}
});
console.log('After going through all new names, the complete list of known names are: ' + existingNames);
Demo where you can play with the code and learn: https://jsfiddle.net/jonahe/11uom4cu/

Randomly selecting unique items from an array with Javascript

I know that there have been a lot of similar questions and I went through most of them. The code that is closest to what I'm trying to achieve is this one.
I have a list of people in each column (which represent a day). for the sake of this question let's assume it's 8 people in each column. I need to randomly select 5 unique people names. I've used splice() to delete the selected item from the array to make sure that it is not selected twice. I'm new to the coding and I think I'm doing some basic mistake as the splice works for the 1st loop and then the array goes back to the original one. Can you, please, help to identify my mistake?
for (var x = 0; x < 5; x++) {
var sourceArray = ss.getRange(49,j+5,8,1).getValues();
var gg = Math.floor(Math.random()*sourceArray.length);
var pickedHLA = sourceArray[gg];
sourceArray.splice(gg, 1);
var HLAselect = ss.getRange(30+x,j+5,1,1)
HLAselect.setValue(pickedHLA);
In your for loop you are redefining the sourceArray during each iteration - you need to define this outside the loop, then do your work to randomly select and remove from the array:
var sourceArray = ss.getRange(49,j+5,8,1).getValues(); //establish full list of people
for (var x = 0; x < 5; x++) {
var gg = Math.floor(Math.random()*sourceArray.length); //get random index
var pickedHLA = sourceArray[gg]; //get random person via random index
sourceArray.splice(gg, 1); //remove random person from full list of people
var HLAselect = ss.getRange(30+x,j+5,1,1)
HLAselect.setValue(pickedHLA);
}
The way you do this is actually quite simple, all it requires a few lines of code:
var arr = ["Cheese", "Purple", "List", "1", "2", "3", "4", "5"];
function random() {
var randomNumber1 = parseInt(Math.random() * arr.length);
var random = arr[randomNumber1];
alert(random);
}
<button onClick="random()">Click Me</button>
There you go!

function to change argument to another sign

I dynamically create this list element and information a user has typed in shows up in it when a button is clicked 'info' is text and shuld show as it is but 'grade' is a number that i want to convert to another sign with the function changeNumber() but I am new to javascript and cant figure out how to make this function, can anyone give a suggestion or point me in the right direction?
var list = $("#filmlista");
var list_array = new Array();
function updateFilmList()
{
document.getElementById("name").value = '';
document.getElementById("star").value = 0;
var listan = list_array[0][0];
var grade = list_array[0][1];
var element = '<li class="lista">' + list + '<span class="grade">'+ changeNumber(grade) +'</span></li>';
list.append(element);
}
should I use innerHTML? not shure I understand how it works? and how do I use the replace method if I have to replace many different numbers to the amount of signs the number is?
for example if the number is 5 it should show up as: *****, if number is 3 show up as: *** and so on
Here's some code that should do the trick:
Add this function into your script.
function changeNumber(number) {
var finalProduct = "";
for (var i = 0; i < number; i++) {
finalProduct += "*";
}
return finalProduct;
}
Replace the updateFilmsList with this code.
document.getElementById("name").value = '';
document.getElementById("star").value = 0;
var listan = list_array[0][0];
var grade = changeNumber(list_array[0][1]);
var element = '<li class="lista">' + list + '<span class="grade">'+ grade +'</span></li>';
list.append(element);
It looks like you're trying to do something like PHP's str_repeat. In that case, take a look at str_repeat from PHPJS
There are options other than a loop:
function charString(n, c) {
n = n? ++n : 0;
return new Array(n).join(c);
}
charString(3, '*'); // ***
You can use innerHTML to set the text content of an element provided none of the text might be mistaken for markup. Otherwise, set the textContent (W3C compliant) or innerText (IE proprietary but widely implemented) property as appropriate.

Make text bold as user types in javascript

I've implemented an auto-completion list in javascript so that if User types 'a', all names starting with 'a' are displayed in drop-down menu. Now I want to make the text bold depending on user input in the drop down menu. So if user types 'ab', the letters 'ab' should appear bold in drop-down menu containing the word about.
Here is some part of my JS code where I'm displaying the names:
document.getElementById('dropmenu').style.visibility='visible';
var element = document.createElement("div");
var namecontainer = document.createElement("div");
namecontainer.setAttribute('id', "name" + div_id);
namecontainer.className = "namecontainerclass";
element.setAttribute('id', "div" + div_id);
element.className = "elementclass";
var text = document.createTextNode(myArray[i].name);
element.appendChild(text);
document.getElementById('dropmenu').appendChild(namecontainer);
document.getElementById("name" + div_id).appendChild(element);
var img=document.createElement("img");
img.setAttribute("src", myArray[i].image);
img.setAttribute("width", 25);
img.setAttribute("height", 25);
namecontainer.appendChild(img);
This is something that came up my mind. You want to check the user-input against the name (myArray[i].name), at that point create some textnodes (or an element if it matches), and append those to the container element (a div in this case). I didn't test it, but it is a bit pseudocode to show how to handle this higlighting without using any javascript framework.
// searchString is the string entered by the user...
// split by the searchString, but group the selection so the matches
// also get added to the result array.
var match = new RegExp('\\('+ searchString +')\\',"gi");
var textParts = myArray[i].name.split(match);
var nodes = [];
var element = document.createElement("div");
// only create elements for names that actually match.
// if there is only one match, there wasn't a match by the split
if (textParts.length > 1){
for(i = 0; i < textParts.length; i++){
if (textParts[i] == searchString) {
nodes[i] = document.createElement("em");
nodes[i].createTextNode(searchString);
} else {
nodes[i] = document.createTextNode(textparts[i]));
}
element.appendChild(nodes[i]);
}
}

Categories

Resources