unable to access object property through bracket variable notation - javascript

I am attempting to access one of the object propertie through a bracket notation, but I can not figure out why it is not working. As always, Your help is greatly appreciated!
js:
var dude = [
{
question1: "What is dude's favourite food?",
choices1: ["Pizza", "Pasta", "Chips", "Ice cream"],
answer1: 1
},
{
question2: "What was dude's first ever job?",
choices2: ["Staples", "Vodafone", "Costa", "Post office"],
answer2: 0
},
]
var counter = 1;
var currentQues = "question"+counter;
console.log(dude[currentQues]);
The console returns "undefined". Is this because it can not access a property through a variable(currentQues), which essentially holds another variable(counter)?
As always, your help is greatly appreciated. I am just a beginner looking to advance.

dude refers to an array of objects. You're trying to access question1 on dude, but you need to access it on dude[0]:
console.log(dude[0][currentQues]);
// -------------^^^
Live Example:
var dude = [
{
question1: "What is dude's favourite food?",
choices1: ["Pizza", "Pasta", "Chips", "Ice cream"],
answer1: 1
},
{
question2: "What was dude's first ever job?",
choices2: ["Staples", "Vodafone", "Costa", "Post office"],
answer2: 0
},
]
var counter = 1;
var currentQues = "question"+counter;
console.log(dude[0][currentQues]);
I would strongly recommend reconsidering that data structure. The names of the properties of the objects should be the same for all the objects, with just their position in the array differentiating them:
var dude = [{
question: "What is dude's favourite food?",
choices: ["Pizza", "Pasta", "Chips", "Ice cream"],
answer: 1
},
{
question: "What was dude's first ever job?",
choices: ["Staples", "Vodafone", "Costa", "Post office"],
answer: 0
},
]
dude.forEach(function(entry, index) {
var num = index + 1;
console.log("Question #" + num + ": " + entry.question);
});

You need to take the index of the array as well.
var dude = [{ question1: "What is dude's favourite food?", choices1: ["Pizza", "Pasta", "Chips", "Ice cream"], answer1: 1 }, { question2: "What was dude's first ever job?", choices2: ["Staples", "Vodafone", "Costa", "Post office"], answer2: 0 }],
counter = 1;
currentQues = "question" + counter;
console.log(dude[counter - 1][currentQues]);
// ^^^^^^^^^^^

Related

Looping over Array of objects and returning random object value - JavaScript

I am trying to loop over an array of objects and display a random quote from the data, so far my code returns undefined. Any idea's why?
Code so far..
const quotesToUse = [{
quote: "This was the biggest quote ever - Array Object",
author: "Derek Bullshido",
},
{
quote: "Hey hows it going - Array Object",
author: "Paul Frank",
},
{
quote: "Why can I say that - Array Object",
author: "Derek Paul",
},
]
function randomQuotes() {
for (var i = 0; i < 1; i += 1 ) {
const randomQuote = quotesToUse[i][Math.floor(Math.random() * quotesToUse[i].quote.length)];
document.getElementById("container").appendChild(text).append(randomQuote);
}
I am trying to display the quote (String) randomly.
You probably want this to get the quote:
const randomQuote = quotesToUse[Math.floor(Math.random() * quotesToUse.length)].quote;
I don't know what you're trying to do with the loop.
You can return random quotes with this function:
const quotesToUse = [{
quote: "This was the biggest quote ever - Array Object",
author: "Derek Bullshido",
},
{
quote: "Hey hows it going - Array Object",
author: "Paul Frank",
},
{
quote: "Why can I say that - Array Object",
author: "Derek Paul",
},
]
function randomQuotes() {
const randomQuote = quotesToUse[Math.floor(Math.random() * quotesToUse.length)];
const quote = document.createElement("DIV");
quote.textContent=randomQuote.quote;
const author = document.createElement("DIV");
author.textContent=randomQuote.author; document.getElementById("container").appendChild(quote).appendChild(author);
}
randomQuotes();
<div id="container"></div>
You can do this more readably with rando.js. Just don't forget to add the script tag to the head of your HTML document if you want to use this code.
const quotesToUse = [
{quote: "This was the biggest quote ever - Array Object", author: "Derek Bullshido"},
{quote: "Hey hows it going - Array Object", author: "Paul Frank"},
{quote: "Why can I say that - Array Object", author: "Derek Paul"},
];
var randomValueFromArray = rando(quotesToUse).value;
console.log(randomValueFromArray.quote);
<script src="https://randojs.com/1.0.0.js"></script>

Count redundancy of answers in array

I have an array of objects like so
[
{_id: "5ca8b8ca0f1b2f54646ded9a", question: "Do you like it?", answer: "yes"},
{_id: "5ca8b8ca0f1b2f54646ded99", question: "Do you like it?", answer: "no"},
{_id: "5ca8b8f80f1b2f54646deda1", question: "Where are you?", answer: "home"},
{_id: "5ca8b8f80f1b2f54646deda0", question: "Where are you?", answer: "home"}
]
and I want it to be reproduced like the following:
[
{
"question": "Do you like it?",
"answers": [{"answer": "yes", "count": 1}, {"answer": "no", "count": 1}]
},
{
"question": "Where are you?",
"answers": [{"answer": "home", "count": 2}]
}
]
I have tried to solve this but i couldn't so any help would be much appreciated. Thank you
We can use Array.find to find the question-answer pair then add a new question-answer pair object if the pair is not existing or update the existing question-answer pair object.
If the question exits but the answer doesn't then simply add the new answer in the answers array.
If both the question and answer exists then increment the answer count property by 1.
If the question itself is missing then add a new object with the question property and answers property and set the count to 1.
Then finally use Array.reduce to accumulate the objects into an array.
const data = [
{_id: "5ca8b8ca0f1b2f54646ded9a", question: "Do you like it ?", answer: "yes"},
{_id: "5ca8b8ca0f1b2f54646ded99", question: "Do you like it ?", answer: "no"},
{_id: "5ca8b8f80f1b2f54646deda1", question: "Where are you ?", answer: "home"},
{_id: "5ca8b8f80f1b2f54646deda0", question: "Where are you ?", answer: "home"}
];
const res = data.reduce((acc, {question, answer}) => {
qFound = acc.find(qa => qa.question === question);
if(qFound){
ansFound = qFound.answers.find(ans => ans.answer === answer);
if(ansFound){
ansFound.count = ansFound.count + 1;
}else{
qFound.answers.push({answer, count:1});
}
}else{
acc.push({
question,
answers: [].concat({answer, count: 1})
});
}
return acc;
},[]);
console.log(res);
use reduce to create objects grouped by question and answer values and then later to discard the keys use Object.values()
const input = [
{_id: "5ca8b8ca0f1b2f54646ded9a", question: "Do you like it ?", answer: "yes"},
{_id: "5ca8b8ca0f1b2f54646ded99", question: "Do you like it ?", answer: "no"},
{_id: "5ca8b8f80f1b2f54646deda1", question: "Where are you ?", answer: "home"},
{_id: "5ca8b8f80f1b2f54646deda0", question: "Where are you ?", answer: "home"}
];
const groupByQuestionAndAnswers = Object.values(input.reduce((accu, {question, answer}) => {
if(!accu[question])
accu[question] = {question};
if(!accu[question][answer])
accu[question][answer] = {answer, count: 0};
accu[question][answer].count += 1;
return accu;
}, {}));
const output = groupByQuestionAndAnswers.map(({question, ...res}) => {
return {question, answers: Object.values(res)};
});
console.log(output);

How can I select a random object from an array and then remove it so it doesn't get repeated?

I'm beginner Javascript student and have to make a trivia game. I have an array of objects which are questions. I want to randomly select an object(question) and then use it, and then get rid of it so that it doesn't get brought up again when I pick the next question. How can I do this correctly? What I have tried so far is:
class Question
{
constructor(t,oA,oB,oC,oD,ans)
{
this.title=t;
this.optionA=oA;
this.optionB=oB;
this.optionC=oC;
this.optionD=oD
this.answer=ans;
}
displayQuestion1R1()
{
userAnswer=prompt(`${this.title}\nA.${this.optionA}\nB.${this.optionB}\nC.${this.optionC}\nD.${this.optionD}`);
}
}
Round1Questions.push(new Question("According to scientists, how old,
approximately, is Earth?", "3 billions years", "100 million years", "4.5
billion years","2.5 billion years", "4.5 billion years"));
Round1Questions.push(new Question("Who was the first American President?",
"Benjamin Franklin", "Barack Obama", "George Washington","Thomas Jefferson",
"George Washington"));
Round1Questions.push(new Question("How many Presidents have there been up to
this year?(2019)?", "45", "40", "60","46", "45"));
Round1Questions.push(new Question("What is the largest Ocean in the world?",
"Atlantic Ocean", "Pacific Ocean", "Indian Ocean","Arctic Ocean", "Pacific
Ocean"));
Round1Questions.push(new Question("Which one of the following is not a
Marvel super-hero?","Spider-Man","Hulk","Batman", "Iron Man", "Batman"));
let ri=RoundQuestions1[Math.floor(Math.random()*Round1Questions.length)];
let question1R1=Round1Questions.splice(ri, 1);
question1R1.displayQuestion1R1();
When I try to run this it says question1R1.displayQuestion1R1() is not a function. However if I remove the splice method I have and just do
let question1R1=RoundQuestions1[Math.floor(Math.random()*Round1Questions.length)];
and then do question1R1.displayQuestion1R1() then it works. However that doesn't allow me to remove the question from the array. How can I accomplish this?
Ok Jack Bashford was close too, but splice method return a array value.
class Question {
constructor(t, oA, oB, oC, oD, ans) {
this.title = t;
this.optionA = oA;
this.optionB = oB;
this.optionC = oC;
this.optionD = oD
this.answer = ans;
}
displayQuestion1R1() {
// userAnswer = prompt(`${this.title}\nA.${this.optionA}\nB.${this.optionB}\nC.${this.optionC}\nD.${this.optionD}`);
console.log( `${this.title}\nA.${this.optionA}\nB.${this.optionB}\nC.${this.optionC}\nD.${this.optionD}` )
}
}
var Round1Questions = [];
Round1Questions.push(new Question("According to scientists, how old, approximately, is Earth ? ",
"3 billions years ", "100 million years ", "4.5 billion years ","2.5 billion years ",
"4.5 billion years ")
);
Round1Questions.push(new Question("Who was the first American President?",
"Benjamin Franklin", "Barack Obama", "George Washington", "Thomas Jefferson",
"George Washington")
);
Round1Questions.push(new Question("How many Presidents have there been up to this year ? (2019) ? ",
"45", "40", "60","46",
"45")
);
Round1Questions.push(new Question("What is the largest Ocean in the world?",
"Atlantic Ocean", "Pacific Ocean", "Indian Ocean", "Arctic Ocean",
"Pacific Ocean ")
);
Round1Questions.push(new Question("Which one of the following is not a Marvel super - hero ? ",
" Spider-Man", "Hulk", "Batman", "Iron Man",
"Batman ")
);
do {
let
PickQuestion_N = Math.floor(Math.random() * Round1Questions.length),
PickedQuestion = Round1Questions.splice(PickQuestion_N, 1)[0]
;
PickedQuestion.displayQuestion1R1();
} while (Round1Questions.length > 0)
Problem
Your approach does not work because of two reasons:
You used RoundQuestions1[Math.floor(Math.random()*Round1Questions.length)] to get your Question instance to assign to r1 variable. Then, you use that instance in Round1Questions.splice(ri, 1), which is not the expected argument type of Array.prototype.splice method.
Round1Questions.splice(ri, 1) returns an Array. So your question1R1 is an array instead of a Question.
Solution
Instead of getting a random Question, try getting a random Quesiton index instead.
Use the random index to splice the Question bank.
Get the first item of the array returned from .splice. See why here.
Working code below (see comments for explanation):
class Question {
constructor(t, oA, oB, oC, oD, ans){
this.title = t;
this.optionA = oA;
this.optionB = oB;
this.optionC = oC;
this.optionD = oD
this.answer = ans;
}
displayQuestion1R1(){
const { title, optionA, optionB, optionC, optionD } = this;
const userAnswer = prompt(`
${title}
A. ${optionA}
B. ${optionB}
C. ${optionC}
D. ${optionD}
`);
}
}
const Round1Questions = [
new Question(
"According to scientists, how old, approximately, is Earth?", "3 billions years",
"100 million years",
"4.5 billion years",
"2.5 billion years",
"4.5 billion years"
),
new Question(
"Who was the first American President?",
"Benjamin Franklin",
"George Washington",
"Thomas Jefferson",
"George Washington"
),
new Question(
"How many Presidents have there been up to this year (2019)?",
"45",
"40",
"60",
"46",
"45"
),
new Question(
"What is the largest Ocean in the world?",
"Atlantic Ocean",
"Pacific Ocean",
"Indian Ocean",
"Arctic Ocean",
"Pacific Ocean"
),
new Question(
"Which one of the following is not a Marvel super-hero?",
"Spider-Man",
"Hulk",
"Batman",
"Iron Man",
"Batman"
)
];
console.log(`Bank before prompt:`, Round1Questions.map(o => o.title));
// Instead of getting the question, get the index of question
let ri = randomQuestionIndex(Round1Questions);
// Use `ri` index to splice your question array.
// Notice the `[0]` to get the first item in the returned array
let question1R1 = Round1Questions.splice(ri, 1)[0];
// No error now because `question1R1` is a `Question` class instance
question1R1.displayQuestion1R1();
console.log(`Bank after prompt:`, Round1Questions.map(o => o.title));
function randomQuestionIndex(bank){
return Math.floor(Math.random() * bank.length);
}
/* NOT RELATED TO YOUR CODE */
/* JUST TO MAKE CONSOLE MORE VISIBLE */
.as-console-wrapper { max-height: 100% !important; }
PS
Don't copy paste any answer here because your professor will immediately find out.

Stringify in objects JSON inside a object JSON

This is my object JSON:
var myJSon = {
"Student": "name",
"Answers":{
"Answer1": {
"question": "question",
"answer": "black",
"time": "00:02:30",
"number_tentatives": "1"
},
"Answer2": {
"question": "question",
"answer": "black",
"time": "00:02:30",
"number_tentatives": "2"
}
}
};
I need to fill in the object "Answer1" or "Answer2". I tried
myJSon.Respostas = JSON.stringify("One","hello","00:03:22","1");
But this results in {Student":"\"name\"","Answers":"\"oi\"}
What I would like is {"Student": "\"name\"", "Answers": {"Answer1": {"question": "One", "answer": "hello" ,"time":"00:03:22" ,"number_tentatives": "1"}, "
If you have an object containing multiple answers, it should be an array or map of answers.
Let's think of your object's initial state as this:
var myJson = {student: 'Student Name', answers: []};
So then you could start filling the answers array like:
myJson.answers.push({question: 'q', answer: 'a', time: 1, number_tentatives: 1});
If you'd now access myJson.answers it would be an array with one answer in it.
If you still think the way to go would be objects (so a 'key' is assigned to each answer), you would do this, instead of push:
myJson.answers['answer1'] = {question: 'q', answer: 'a', time: 1, number_tentatives: 1};
If you want to add additional data, then you could try this:
myJSon.Answers.Answer3 ={"question":"One","answer":"hello","time":"00:03:22","number_tentatives":"1"};
then test it like
console.log(JSON.stringify(myJSon));

Get key Json and search with name var [duplicate]

This question already has answers here:
Accessing an object property with a dynamically-computed name
(19 answers)
Closed 7 years ago.
I have the following problem:
I have the following JSON:
var words = {
"categorias": [
{
"Licores": ["Smirnoff", "Johnnie Walker", "Bacardi", "Martini", "Hennessy", "Absolut", "Jack Daniels", "Chivas Regal", " Baileys", "Ballantines", "CAPTAIN MORGAN", "CUERVO", "JAEGERMEISTER", "MOET ET CHANDON", "DEWARS", "JIM BEAM", "GALLO", "HARDYS", "CROWN ROYAL", "RICARD", "CONCHA Y TORO", "GREY GOOSE", "GORDONS", "GRANTS", "JAMESON", "MALIBU", "STOLICHNAYA", "MARTELL", "HAVANA CLUB", "REMY MARTIN", "PATRON", "YELLOWTAIL", "SAUZA", "SKYY", "FINLANDIA", "BERINGER", "TANQUERAY", "DREHER", "BEEFEATER", "BOMBAY", "SEAGRAM", "CANADIAN CLUB", "GLENFIDDICH", "COINTREAU", "TEACHERS", "KAHLUA", "BELLS", "CINZANO VERMOUTH", "LINDEMANS", "COURVOISIER", "CANADIAN MIST", "TORRES", "INGLENOOK", "CASTILLO", "KUMALA", "PENFOLDS", "LANSON", "Ron", "Vodka", "Whisky", "Bourbon", "Brandy", "Cognac", "Tequila", "Ginebra", "Vino blanco", "Vino tinto", "Champagne", "Cerveza", "Budweiser", "Heineken", "Sambuca", "Frangelico", "Triple Sec", "Licor de cafe", "Kirsch", "Fernet", "Aguardiente", "Pisco", "Sangría", "Mojito", "Margarita", "Cuba libre", "Daiquiri", "Cosmopolitan", "Caipirinha", "White Russian", "Coco Loco", "Mai Tai", "Manhattan", "Zombie", "Gintonic", "Hurricane", "Negroni", "Paloma", "Farnell"]
},
{
"animales": ["Abadejo", "Abanto", "Abeja", "Abeja doméstica", "Abejorro", "Abubilla", "Abulón", "Acedía", "Acentor", "Acevia", "Acocil", "Acranio", "Actinia", "Addax", "Agachadiza", "Aguará", "Águila", "Agutí", "Ajolote", "Alacrán", "Albatros", "Alburno", "Alcaraván", "Alcatraz", "Alcaudón", "Alce", "Alcélafo", "Alimoche", "Almeja", "Alondra ibis", "Alosa", "Alpaca", "Alzacola", "Ameba", "Ampelis", "Anaconda", "Anchoa", "Anfioxo", "Angelote", "Anguila", "Aninga", "Anoa", "Anolis", "Ánsar", "Anta", "Antílope", "Araguato", "Araña", "Arapaima", "Arapapa", "Ardilla", "Arenque", "Argonauta", "Armadillo", "Armiño", "Arrendajo", "Asno", "Atún", "Avefría", "Avestruz", "Avispa", "Avetoro", "Avispón", "Avoceta", "Avutarda", "Ayeaye", "Ayu", "Babirusa", "Babosa", "Babuino", "Bacalao", "Baiji"]
}
]
}
So when I want search a Categoria I call this function:
function random(max){
return Math.floor((Math.random() * max) + 0);
}
Now as the Key of JSON is a array (categorias), and this key i want get of way random, then i use Object.keys(), and it runs smoothly, when i assigned the var namKeyJson to Object.keys(words.categorias[randomCategory]), i returned the name of the key which i need
var lengthCategory = words.categorias.length-1;
var randomCategory = random(lengthCategory);
var nameKeyJson = Object.keys(words.categorias[randomCategory]);
nameKeyJson = nameKeyJson.toString();
the problem is when i want get the values or the length the categorys of array, and that by placing the variable nameKeyJson, takes the name of the variable but not its value.
var lengthPregunta = words.categorias[randomCategory].nameKeyJson.length;
console.log(lengthPregunta);
Thanks for help me.
var lengthPregunta = words.categorias[randomCategory].nameKeyJson.length;
Should be
var lengthPregunta = words.categorias[randomCategory][nameKeyJson].length;
You try to call 'nameKeyJson' from words.categorias[randomCategory] instead of indexing key by nameKeyJson.
Use bracket notations:
words.categorias[randomCategory][nameKeyJson]
and with your code it will always return only first variable.
So change
var lengthCategory = words.categorias.length-1; to
var lengthCategory = words.categorias.length;
var words = {
"categorias": [{
"Licores": ["Smirnoff", "Johnnie Walker", "Bacardi", "Martini", "Hennessy", "Absolut", "Jack Daniels", "Chivas Regal", " Baileys", "Ballantines", "CAPTAIN MORGAN", "CUERVO", "JAEGERMEISTER", "MOET ET CHANDON", "DEWARS", "JIM BEAM", "GALLO", "HARDYS", "CROWN ROYAL", "RICARD", "CONCHA Y TORO", "GREY GOOSE", "GORDONS", "GRANTS", "JAMESON", "MALIBU", "STOLICHNAYA", "MARTELL", "HAVANA CLUB", "REMY MARTIN", "PATRON", "YELLOWTAIL", "SAUZA", "SKYY", "FINLANDIA", "BERINGER", "TANQUERAY", "DREHER", "BEEFEATER", "BOMBAY", "SEAGRAM", "CANADIAN CLUB", "GLENFIDDICH", "COINTREAU", "TEACHERS", "KAHLUA", "BELLS", "CINZANO VERMOUTH", "LINDEMANS", "COURVOISIER", "CANADIAN MIST", "TORRES", "INGLENOOK", "CASTILLO", "KUMALA", "PENFOLDS", "LANSON", "Ron", "Vodka", "Whisky", "Bourbon", "Brandy", "Cognac", "Tequila", "Ginebra", "Vino blanco", "Vino tinto", "Champagne", "Cerveza", "Budweiser", "Heineken", "Sambuca", "Frangelico", "Triple Sec", "Licor de cafe", "Kirsch", "Fernet", "Aguardiente", "Pisco", "Sangría", "Mojito", "Margarita", "Cuba libre", "Daiquiri", "Cosmopolitan", "Caipirinha", "White Russian", "Coco Loco", "Mai Tai", "Manhattan", "Zombie", "Gintonic", "Hurricane", "Negroni", "Paloma", "Farnell"]
}, {
"animales": ["Abadejo", "Abanto", "Abeja", "Abeja doméstica", "Abejorro", "Abubilla", "Abulón", "Acedía", "Acentor", "Acevia", "Acocil", "Acranio", "Actinia", "Addax", "Agachadiza", "Aguará", "Águila", "Agutí", "Ajolote", "Alacrán", "Albatros", "Alburno", "Alcaraván", "Alcatraz", "Alcaudón", "Alce", "Alcélafo", "Alimoche", "Almeja", "Alondra ibis", "Alosa", "Alpaca", "Alzacola", "Ameba", "Ampelis", "Anaconda", "Anchoa", "Anfioxo", "Angelote", "Anguila", "Aninga", "Anoa", "Anolis", "Ánsar", "Anta", "Antílope", "Araguato", "Araña", "Arapaima", "Arapapa", "Ardilla", "Arenque", "Argonauta", "Armadillo", "Armiño", "Arrendajo", "Asno", "Atún", "Avefría", "Avestruz", "Avispa", "Avetoro", "Avispón", "Avoceta", "Avutarda", "Ayeaye", "Ayu", "Babirusa", "Babosa", "Babuino", "Bacalao", "Baiji"]
}]
}
function random(max) {
return Math.floor((Math.random() * max) + 0);
}
var lengthCategory = words.categorias.length;
var randomCategory = random(lengthCategory);
var nameKeyJson = Object.keys(words.categorias[randomCategory]);
var lengthPregunta = words.categorias[randomCategory][nameKeyJson].length;
console.log(lengthPregunta);

Categories