People guesser program with JavaScript objects - javascript

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.

Related

Am i thinking clearly here in creating a new object?

let person = {
name:"kevin",
eyeColor:"blue",
age: 34,
address: {
street: "12 havering road",
town: "romford",
house: {
type: "terraced",
bedrooms: 3,
}
},
updateAge: function () {
let age = ++person.age;
return age;
}
};
console.log(person.updateAge());
let details = person.address.house;
alert(details.type);
Hello everyone, I have a burning question in regards to objects. I must say when i am watching tutorials on this , most are unclear as i like to understand concepts instead of just end goal's but i cant seem to find much material in regards to the concepts so after several hours of playing with the console. i have come up with this. I may be completely wrong but need to ask for my sanity. The code above i am imagining var person as the global window object. Address as the document( a property of the window object) . house as the getElementById ( i know thats a method compared to a property but im only focusing on the pathway accessing properties and methods in objects. Then im assuming im assigning all to a varialbe and then .type is like .innerHTML.
So although obviously funcitonally not the same. am i correct in saying including the window global object the pathway to e.g.
var box = window.document.getElementById('box');
box.innerHTML =
IS THE SAME AS
var box = person.address.house;
box.type =
Obvs ignore the functionality but the pathway of creating my own objects, am i correct in saying is a similar setup ?
thanks all
I think I understand what you are asking. window.document.getElementById('box').innerHTML is similar to calling person.address.house.type. However, I must point out that the window object is a built in javascript object and your person object was created by you. The window object is made up of a bunch of properties and methods, which then contains nested properties and methods, which is similar to your person object!
If you ever want to see what properties and methods an object contains you can use console.dir():
console.dir(window);
let person = {
name:"kevin",
eyeColor:"blue",
age: 34,
address: {
street: "12 havering road",
town: "romford",
house: {
type: "terraced",
bedrooms: 3,
}
},
updateAge: function () {
let age = ++person.age;
return age;
}
};
console.dir(person);

Iterating through dictionary inside class object in JavaScript

I have a class:
class Quizer {
// construct new quiz for unique user
constructor(quizObj) {
this.quiz = quizObj;
this.currentQuestionNum = 0;
this.userSelections = [];
}
...
buttonAction(setup) {
//var text = this.quiz.question1.question; <-- //works
var text = this.quiz[currentQuestionNum].question; // doesnt work
}
}
That is constructed here:
var quiz = new Quizer(questionObjects);
Where questionObjects is:
var questionObjects = {
question1: {
question: "Darwin explained his theory of evolution in a book called?",
choices: [
"this is the correct answer, choose me!",
"On the Origin of Species",
"Survival of the Fittest"
],
correctAnswer: "On the Origin of Species"
},
question2: {
...
}
}
In buttonAction, my goal is to iterate through questionObjects and get each question. Can someone help me with the syntax?
You need something like this
for(var key in questionObjects){
// The following gives you the question for the current key
questionsObjects[key].question
}
As it is stated here:
The for...in statement iterates over the enumerable properties of an
object, in arbitrary order. For each distinct property, statements can
be executed.

CodeAcademy javascript questing

I am working on codeAcademy's javascript section and I am so stuck on one of the exercises.
Here is my code:
var friends = {
bill:{
firstName:"Bill",
lastName: "Gates",
number:"(206)555-5555",
address:['One Microsoft Way', 'Redmond','wa','12345']
}
};
var friends = {
steve:{
firstName:"Steve",
lastName: "Jobs",
number:"(555)555-5555",
address:['One Apple Way', 'San Diego','ca','12345']
}
};
var list = function()
{
for (var something in friends)
console.log(something);
}
var search = function(name)
{
for (var contact in friends)
{
if (contact == name)
{
for (var contact_info in friends.name)
{
console.log(contact_info);
}
}
}
}
I am pretty confused about the for/in loop. I have been working on this exercise for a while and was wondering if someone could help me understand. Mainly the search function. Its suppose to be able to see if the given name is in the the object and print the contact info associated. I am completely lost. I even tried restarting the whole section and still got stuck.
In Javascript, the for-in loop will go through each of an object properties.
Your friends object is first created having only one property, which is also an object, describing Bill Gates. Then it it overwritten by another object that also has only one property, but now describing God Steve Jobs.
Finally, in the search function, you are going through each property of friends and comparing them to a string. Inside a for-in loop, name is a variable that contains the name of the property used in the current iteration of the loop. So you'll get a match if you use the names of the variables (i.e.: steve). If you wish to match the names stored in the object, you have to use a parameter that is not called name in the declaration of the search function, and make the check like this:
if (contact.firstName == _name || contact.lastName == _name ||
(contact.firstName + " " + contact.lastName) == _name)
Also notice that after you create your friends variable with Bill, you then recreate it with Steve. So you end up with only one "contact" in that variable. You could change your object declarations like this:
var friends = {}; // This creates an empty object
friends.bill = {
firstName: "Bill",
lastName: "Gates" // And so on...
};
friends.steve = {
firstName: "Steve" // You get the drill
};
And then your friends object would have both pirates of the Sillicon Valley now.
First of all you have wrong friends var definition, you override Bill with Steve.
It suppose to be similar to this
var friends = {
bill:{
firstName:"Bill",
lastName: "Gates",
number:"(206)555-5555",
address:['One Microsoft Way', 'Redmond','wa','12345']
},
steve:{
firstName:"Steve",
lastName: "Jobs",
number:"(555)555-5555",
address:['One Apple Way', 'San Diego','ca','12345']
}
};
Now the answer to your question.
function search(name)
{
// Length of friends object received using Object.keys
for (var p = 0; p < Object.keys(friends).length ;p++)
{
if(friends[name] != undefined){
// Add to console and stop function execution if match found.
console.log(friends[name].firstName);
return;
}
}
}
Some explanation.
If "friends[name]" is undefined it means that you don't have object with specified name.
If it returns some Object you just get the value of the "firstName" or any other property in the object.
A for in loop in Javascript will loop through each property of an object. Unfortunately, your object will only have 1 property steve because you overwrite the entire object with your second var friends = ... statement. When looping through an object, your name variable will be the string index of your friend in the friends object. Once you find a match for the name, you can use the contact information by using friends[name]. If you are looking for a friend with the same first name as your search, you may want to look at the specific first name
Just as a side note, because Javascript is a loosely typed language, there is no need to loop through the entire friends object to see if you have a friend with that name. Here is a code sample:
var friends = {
bill: {
firstName: 'Bill',
lastName: 'Gates'
},
steve: {
firstName: 'Steve',
lastName: 'Jobs'
},
steve2: {
firstName: 'Steve',
lastName: 'Doe'
}
},
search1 = function(name) {
if(friends[name] !== undefined) { //Is there a friend with this index
//Yay, we have a friend with this index!
}
else {
//Sorry, we don't have a friend with this index
}
},
search2 = function(name) {
name = name.toLowerCase(); //Case insensitive
for(var friend in friends) {
if(friends[friend].firstName.toLowerCase() == name) { //Does this person have the same first name
//This friend has the same first name
}
}
};
search1('steve'); //Will only give us Steve Jobs
search2('steve'); //Will give us Steve Jobs and Steve Doe

Not understanding how to load class properties from an array

I would appreciate some help. I am trying to do a small javascript program that does the following:
1) I already have a few arrays with some information about different cars. For example:
var brand = ["Audi", "Ford", "Peugeot", "Nissan"];
var color = ["red", "black", "black", "white"];
2) Then, I would like to create a class that creates a new car and receives the properties through a method that retrieves them from the ones I have stored in the array,
Is something like this correct?
function newcar() {
this.prototype.loadinfo = function() {
var cbrand = brand[0];
var ccolor = color[0];
}
}
Sorry if this is horribly wrong, but the reason I am asking is that I didn't find any information about this particular case on the webpages I checked. Since I am trying to learn javascript just with internet tutorials, I tried to guess the solution as good as I could!
And in case it's correct (sort of) or that the correct version is very similar, I cannot understand how I should advance in the array while I create new cars. For example, if I run it once, the first car created will receive the information on the position [0], but if I run it twice or more times... how can I know in which position of the array I should find the information?
I am quite confused with this subject. I will be very grateful if someone can give me some advice. In the meantime, I continue reading about it, to see if I find out something else.
Thanks!
If I understand correctly you want to create a new car object for as many brands in the array. The first thing is to fix your constructor. Note that constructors are capitalized as a convention and the prototype should be declared outside, but you don't need the prototype because you're dealing with unique properties not shared methods. Then you can pass 2 parameters that will be assigned to the properties. In other words:
function Car( brand, color ) {
this.brand = brand;
this.color = color;
}
If you need a method to read those properties add it to the prototype like:
Car.prototype = {
loadInfo: function() {
alert( this.brand +':'+ this.color );
}
};
Finally, to create a new car for every item in the array you'd do it like this:
var cars = [];
for ( var i = 0; i < brand.length; i++ ) {
cars.push( new Car( brand[i], color[i] ) );
}
Now you have 4 cars in the cars array, and each car will be a different brand and color.
But better yet, you can organize your brands and colors in an object and a for...in to create new cars:
var cars = {
Audi: 'red',
Ford: 'black',
Peugeot: 'black',
Nissan: 'white'
};
var mycars = [];
for ( var c in cars ) {
mycars.push( new Car( c, cars[c] ) );
}

.push() multiple objects into JavaScript array returns 'undefined'

When I add items to the beats array and then console.log the User, I'm getting the correct number of items in the array. But when I check .length, I always get 1.
Trying to call the index will always give me 'undefined' like so:
Tom.beats[1]
I think I'm missing something obvious, but this is beating me. I suspect that I'm misusing the .push method but I'm unsure. Any help is greatly appreciated!
(using Chrome dev tools)
//The USER
function User(name, role){
this.beats = [ ];
this.name = name;
this.role = role;
// add beats to beats array
this.addBeats = function(beats){
return this.beats.push(beats);
};
}
// Three New Instances. Three New Users.
var Mal = new User("Mal", "Rapper");
Mal.addBeats(["love", "cash"]);
var Dan = new User("Dan", "Producer");
Dan.addBeats(["cake", "dirt", "sally-mae"]);
var Tom = new User("Tom", "Producer");
Tom.addBeats(["Fun", "Little", "Samsung", "Turtle", "PC"]);
// Check for position in beats array
console.log(Tom.beats);
console.log(Mal.beats);
console.log(Dan.beats);
console.log(Mal.beats[1]);
console.log(Dan.beats[1]);
console.log(Tom.beats[1]);
Array.push(...) takes multiple arguments to append to the list. If you put them in an array itself, this very array of "beats" will be appended.
Array.concat(...) is most likely not what you are looking for, because it generates a new array instead of appending to the existing one.
You can use [].push.apply(Array, arg_list) to append the items of the argument list:
this.addBeats = function(beats) {
return [].push.apply(this.beats, beats);
};
Spread operator
In environments that support the spread operator you may now do the following:
this.addBeats = function (beats) {
return this.beats.push(...beats);
};
Or if you need more control for overwriting etc
this.addBeats = function(beats) {
return this.beats.splice(this.beats.length, null, ...beats);
};
addBeats() should concat this.beats with the beats parameter.

Categories