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
Related
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);
I was trying to access sub-properties from a javascript file and it's giving me something weird!
Suppose this is my JS file named data.js
module.exports = {
something: {
name: "Something",
num: 1,
email: "something#gmail.com"
},
somethingtwo: {
name: "Something Something",
num: 2,
email: "somethingtwo#gmail.com"
},
};
In my main js file named app.js, where I need to access it, it looks like
var persons = require('./data.js');
var getAName = function() {
for(var name in persons) {
console.log(name.email);
}
}
I really don't know what goes wrong but I have been trying this for quite a long time now. The expected output is the email Ids from the data.js file but instead, i get undefined times the number of entries (if there are 2 entries in data.js, then I get 2 undefine and so on).
How can I access the email or the num from the data.js without those undefines?
console.log(name) is returning something somethingtwo
Well, name.email is undefined because name is a string.
You can test that by writing
console.log(typeof name);
Now, to solve your problem, you need to access the property correctly:
var getAName = function() {
for (var name in persons) {
console.log(persons[name].email)
}
}
Returns:
something#gmail.com
somethingtwo#gmail.com
for(var name in persons) {
//persons is actually an object not array
//you are actually iterating through keys of an object
//var name represent a key in that object
console.log(persons[name]); //value corresponding to the key
}
I guess this code will give you the desired result.
You should be using console.log(persons[name].email)
require don't automatically calls the module
var DataArchive = require('./data.js');
var module = DataArchive.module;
var persons = module.exports;
var getAName = function() {
for(var person in persons) {
//person should be something (first iteration) and somethingtwo (second iteration)
console.log(person.email);
}
In C#, I can create a class that acts as a user-defined type, such as:
Public Class FullName
{
string FirstName;
string LastName;
}
Public Class Address
{
string Line1;
string Line2;
string City;
string State;
string Zip;
}
and then I can create:
Public Class Person
{
FullName Name;
Address HomeAddress;
Address WorkAddress;
}
This allows me to reference the data like:
Person Bob;
Bob.WorkAddress.Line1 = "123 Sycamore Rd";
Bob.HomeAddress.Line1 = "1313 MockingBird Ln";
Bob.FullName.LastName = "Smith";
etc...
Ultimately, I want to create a 2D array of Person, so I don't want to hardcode (pre-populate?) the data until I know what it is.
I'd like to be able to do the same thing in JavaScript (specifically node.js), but can't seem to find an obvious way of doing so. Is this just fundamentally the wrong approach, or am I just missing something?
In Javascript you can create data objects directly (no classes):
var bob = {
workAddress: { line1: "123 Sycamore" },
fullName: { lastName: "Smith" }
};
It's also possible to create a class, but it's usually not necessary for mere data objects.
Ultimately, I want to create a 2D array of Person, so I don't want to hardcode (pre-populate?) the data until I know what it is.
You can create an array and later add persons to it:
var persons = [];
...
persons.push(bob);
For a 2D array, create an array to contain your person arrays:
var persons2D = [];
...
persons2D.push(persons);
A really good example of javascript objects and their notation would be JSON.org
Here is an object that has 2 string properties, and a 3rd property which is an array. One slight difference is that because javascript is not strongly typed, the "residents" property could just be a simple string or an array. So you have to be careful when parsing as any property could be either a string or another array.
var household = {
address: "1234 N 56th st"
, city: "somewhere"
, residents: [
{ Name: "My Name" }
, { Name: "My Alias" }
]
};
Now depending on how you are sourcing the data, you can use the javascript or JSON (de)serialize methods within C# to populate.
I made a HTML project called Customer with some text boxes where can I enter some text and a button called save.Now I want to create a function in JavaScript to save a new contact object.
I tried this:
function SaveContact() {
var list = [];
var firstName = document.getElementById("first_name");
var lastName = document.getElementById("last_name");
var phoneN = document.getElementById("phone");
var emailN = document.getElementById("email");
var birthDay = document.getElementById("birth_day");
var birthMonth = document.getElementById("birth_month");
var birthYear = document.getElementById("birth_year");
list.push({ firstName, lastName, phoneN, emailN, birthDay, birthMonth, birthYear });
return list;
But it doesn't change anything. Where am I wrong?
The problem with the following line:
list.push({ firstName, lastName, phoneN, emailN, birthDay, birthMonth, birthYear });
is that you're only saving values. In JS, you need both values and keys. Therefore, you would need to change it to:
list.push({ "firstName": firstName, "lastName": lastName, "phoneN": phoneN, "emailN": emailN, "birthDay": birthDay, "birthMonth":birthMonth, "birthYear":birthYear });
EDIT
You say you want to create an object but you want to store them as an array. To store them as an array (an object with keys as their indeces), just remove the { and } in the push() line.
However, I think it would be easier to just create an object, like so:
function SaveContact() {
return {
"firstName": document.getElementById("first_name"),
"lastName": document.getElementById("last_name"),
"phoneN": document.getElementById("phone"),
"emailN": document.getElementById("email"),
"birthDay": document.getElementById("birth_day"),
"birthMonth": document.getElementById("birth_month"),
"birthYear": document.getElementById("birth_year")
};
}
This one-statement function simply creates and returns an object literal, rather than assigning the values to variables and then putting them into an array/object.
But if you really do want an array, just replace the { and } with [ and ] and remove the keys. This will get you the output you are currently trying to achieve with your program.
Push does not need the { ... } around the elements:
array.push(item1, item2, ..., itemX)
(from here)
Also, note that you are storing DOM Elements in the the list. You probably need their values and not the elements but it depends on what you try to do...
EDIT - after seeing Jonathan's answer
Alternatively you can do:
obj = {}
obj.name = document.getElementById("first_name")
// ... more fields
list.push(obj)
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.