6. List em all - Not sure I understand this?


#1

var friends = {
bill: {
firstName: "Bill",
lastName: "Gates",
number: "(206) 555-555",
address: ['One Microsoft Way', 'Redmond', 'WA', '98052']
},
steve: {
firstName: "Steve",
lastName: "Jobs",
number: "(205) 555-5555",
address: ['Apple City, LostInSpace Drivethrough', 'Whereva', 'FU', '12345']
}
};


**// 6. List em all - Not sure I understand this?**

var list = function(friends){   ** // function created is called list**  
can this be written without having variable named friends inside the parameter( )? like so?
var list = function( ){

for( var dunno in friends){  **// object friends** ?? 
// so am i right in thinking the variable **dunno** stores *object friends?*

console.log(dunno); // prints out variable dunno which contains list of 
}
}

list(friends); // returns or calls the ***list function***  so it appears in the console?

when i first tried this I initially wrote it differently:-
list(dunno);

I though It needed to be variable dunno instead of variable named friends?

trial and error resulted in correct output and swapping variable to friends instead but I don't seem to follow this reasoning.


#2

found a couple of forum listings that helped me to gain a broader understanding of this lesson one link may also assist others who find it a bit confusing:

simpler example of how a for / in loop works :

a link to another site:
http://www.w3schools.com/js/js_loop_for.asp

offers alternative explanation of for/in loop

The For/In Loop
The JavaScript for/in statement loops through the properties of an object:

Example
var person = {fname:"John", lname:"Doe", age:25};

var text = "";
var x;
for (x in person) {
text += person[x];
}

Output result:
John Doe 25

and the helpful clarification provided by Leon
https://www.codecademy.com/forum_questions/545275fd8c1ccc8e3e000a23#comment-5457b12c9c4e9d87cb00003f

helps me gain a clearer perspective on properties:

keep repeating these two lines
An object has one or more properties seperated by a comma-,
Each property consists of a property-key and it's associated value

Description of the friends object.
The friends object has 2 properties and are seperated by a comma-,

there is a bill property with property-key bill and it's associated object value
(this associated object has 4 properties, the property-keys being firstName, lastName,number and address)
there is a steve property with property-key steve and it's associated object value
(this associated object has 4 properties, the property-keys being firstName, lastName,number and address)


#3

To the question regarding the parameter, (friends), it depends upon what the lesson instructions ask for. friends is a globally defined object, so visible inside a function in any scope:

var list = function () {
    for (var key in friends) {
        // friends object is visible
    }
};

We must assume that friends does exist, and is an enumerable object. This will also work,

var list = function (friends) {
    for (var key in friends) {
        // friends object is visible
    }
};

In both of these examples there is a problem of re-usability. Neither function can be used by objects other than friends. An improvement upon this would be a form of function that does not make assumptions.

var list = function (obj) {
    for (var key in obj) {
        // obj is a reference to the argument 'friends'
    }
};
list(friends);

#4

Ah - thx. That makes a lot more sense now too. Appreciate you posting this as I am just about to make a start on the next unit so I understand this a lot better and thanks to your clarification even understanding why we call friends through the use of: list(friends);

var list = function(friends){
for( var dunno in friends){
console.log(dunno);
}
}
list(friends);

so I have added this explanation into my notes thanks.


#5

To the dunno question,

for (var key in obj)

key in this instance is the index variable referring to individual object keys in obj. It can be given any name, but a practical one is best. We know that it refers to keys, so that is good start, but any will do.

for (var friend in friends)

This is okay, though it doesn't speak of practicality. For readability it may have some merit. I'm in favor of generalized or generic names, but only have an opinion, not a firm recommendation on this matter.

Given the object,

var friends = {
    bill: {},
    steve: {},
    ada: {}
};

bill, steve and ada are the primary keys of the friends object. These are the names that are iterated by key in the for..in statement.

var list = function (obj) {
    for (var key in obj) {
        console.log(key);
    }
};
list(friends);
bill
steve
ada

We can refer to the values associated with the keys by using them as the subscript variable:

var list = function (obj) {
    for (var key in obj) {
        console.log(key + ": " + obj[key]);
    }
};
list(friends);
bill: {}
steve: {}
ada: {}

Objects are not ordered, so the order in which these print out may change from one rendering to the next.


#6

again many thanks for taking the time to explain this so I am better able to understand the purpose of this unit. When I saw the next unit is Objects I was reluctant to proceed but thankfully a few other forum postings with further explanations on the topic in general and your clarification of the two particular aspects I was not fully comprehending (which I have added into my notes) have been a big help and so I am a bit less anxious to proceed to unit 7.

Appreciate your patience in breaking down both the property-key and it's associated value and the rationale as to why obj is a reference to the argument 'friends' so it makes more sense now why we call list(friends); and not call list(dunno);

I think its slowly beginning to sink in and hopefully the next unit will build on this.


#7

My code logs on the console the 'search' for steve but there's also 'Bills' info somewhere in there, why is this si and how to stop it

Here's my code

var friends = {}
friends.bill = {
firstName: "Bill",
lastName : "Gates",
number: "(+004)-9128-887009",
address: ['One Street', 'Bulvard Way', 'CA', '344']
};
friends.steve = {
firstName: "Steve",
lastName: "Jobs",
number: "+34-00-899-034",
address: ['Little Ave', '23', 'LA', '001']
};
for (var bill in friends) {
console.log(bill);
};
var list = function(friends){

};

var search = function(name){
for (var bill in friends){
if (friends[bill].firstName === name) {
console.log(friends[bill]);
return friends[bill];
}
};
};
//list (friends);
search("Steve");

And the output looks something like this:

number: '+34-00-899-034',
address: [ 'Little Ave', '23', 'LA', '001' ] }
{ firstName: 'Steve',
lastName: 'Jobs',
number: '+34-00-899-034',
address: [ 'Little Ave', '23', 'LA', '001' ] }
{ firstName: 'Steve',
lastName: 'Jobs',
number: '+34-00-899-034',
address: [ 'Little Ave', '23', 'LA', '001' ] }
{ firstName: 'Bill',
lastName: 'Gates',
number: '(+004)-9128-887009',
address: [ 'One Street', 'Bulvard Way', 'CA', '344' ] }
{"firstName":"Steve","lastName":"Jobs","number":"+34-00-899-034","address":["Little Ave","23","LA","001"]}


#8

@gregoryb_erns

I think, based on what has been explained to me, when i read your code:

for (var bill in friends) {
console.log(bill);
};

you have named the key as bill

so, it seems this is still going to still bring up a list of all your friends when calling the list (friends);

@mtf clarified this aspect for me too in his post mentioned above:

for (var key in obj)
key in this instance is the index variable referring to individual object keys in obj. It can be given any name, but a practical one is best. We know that it refers to keys, so that is good start, but any will do.

for (var friend in friends)
This is okay, though it doesn't speak of practicality.

so with your code:

for (var bill in friends) {
console.log(bill);
};

bill is what you have allocated as a name for the property key

for (var key in obj)
which you have written as code like so:
for(var bill in friends)

and so with both the search and the list when you call them via either the return mode or the console.log( ) mode it will not just return your friend bill's details but instead return the data associated with the property key ( which you have named 'bill') in your code:

console.log(bill); // this is going to display what is associated to the property key you named 'bill'

as you have indicated in the for/in loop:

for (var bill in friends) {
console.log(bill);
};

Whereas, I think in the search function code you are indeed searching for a friend whose first name is Steve and the search has located and returned to the console for you a friend named Steve which it found via searching within the associated property key (you named 'bill') :

var search = function(name){
for (var bill in friends){
if (friends[bill].firstName === name) {
console.log(friends[bill]);
return friends[bill];
}
};

that means the output you see is not incorrect per se, as the instructions given have been carried out according to your code request:

search("Steve"); // output when your code is run in repl.it:

number: '+34-00-899-034',
address: [ 'Little Ave', '23', 'LA', '001' ] }
{ firstName: 'Steve',
lastName: 'Jobs',
number: '+34-00-899-034',
address: [ 'Little Ave', '23', 'LA', '001' ] }

list (friends); // output when your code is run in repl.it:

bill
steve

Not sure why your output shows:

{ firstName: 'Steve',
lastName: 'Jobs',
number: '+34-00-899-034',
address: [ 'Little Ave', '23', 'LA', '001' ] }
{ firstName: 'Bill',
lastName: 'Gates',
number: '(+004)-9128-887009',
address: [ 'One Street', 'Bulvard Way', 'CA', '344' ] }
{"firstName":"Steve","lastName":"Jobs","number":"+34-00-899-034","address":["Little Ave","23","LA","001"]}

the fact the steve is the first friend name showing in the list(friends); output is coincidental, which again, is down to lists displayed being unordered as @mtf also pointed out in his second reply post when he answered the second part of my own query:

Objects are not ordered, so the order in which these print out may change from one rendering to the next.

sorry I can't explain it better for you - its just starting to make sense to me too.

I don't really know how, at this stage, you would amend the code to stop it other than maybe trial and error - such as deleting the list(friends) code that calls this request for that data.

Maybe this will be covered in the next unit (Objects I) though there is a good chance that maybe someone reading this post and is more knowledgeable can help you with that aspect and might even clarify what I have written in a simpler way for you


#9

@awalklean,

Thanks for this response, I will try change bill to firstName instead and see how this works out.

Thanks, I'll get the hang of it eventually...


#10

@gregoryb_erns

when you change bill to firstName you are still only changing the key name

so the code would still have the same information and when called it would still continue to display the first names of the friends details you have saved:

var friends = {}
friends.bill = {
firstName: "Bill",
lastName : "Gates",
number: "(+004)-9128-887009",
address: ['One Street', 'Bulvard Way', 'CA', '344']
};
friends.steve = {
firstName: "Steve",
lastName: "Jobs",
number: "+34-00-899-034",
address: ['Little Ave', '23', 'LA', '001']
};
for (var firstName in friends) {
console.log(firstName);
};

// output when your code is run in repl.it:

bill
steve

The only way I worked out to omit listing the name of friends from your code was by going to the for/in loop and actually commenting out the console.log( ); line of code using the // comments option so the console window would just show the name search for a single friend found in the friends data:

var friends = {}
friends.bill = {
firstName: "Bill",
lastName : "Gates",
number: "(+004)-9128-887009",
address: ['One Street', 'Bulvard Way', 'CA', '344']
};
friends.steve = {
firstName: "Steve",
lastName: "Jobs",
number: "+34-00-899-034",
address: ['Little Ave', '23', 'LA', '001']
};
for (var assocKey in friends) {
// if you don't want this to show on console window
// console.log(assocKey);
};

var list = function(friends){

};

var search = function(name){
for (var assocKey in friends){
if (friends[assocKey].firstName === name) {
//console.log(friends[assocKey]);
return friends[assocKey];
}
};
};

search("Bill");

// output when your ONLY return code from the search function is run in repl.it:

=> { firstName: 'Bill',
lastName: 'Gates',
number: '(+004)-9128-887009',
address: [ 'One Street', 'Bulvard Way', 'CA', '344' ] }

// output when ONLY your console.log( ); code from the search function is run in repl.it:

{ firstName: 'Bill',
lastName: 'Gates',
number: '(+004)-9128-887009',
address: [ 'One Street', 'Bulvard Way', 'CA', '344' ] }

// output when both your console.log( ); AND return code from the search function are run in repl.it:

{ firstName: 'Bill',
lastName: 'Gates',
number: '(+004)-9128-887009',
address: [ 'One Street', 'Bulvard Way', 'CA', '344' ] }
=> { firstName: 'Bill',
lastName: 'Gates',
number: '(+004)-9128-887009',
address: [ 'One Street', 'Bulvard Way', 'CA', '344' ] }

I think what @mtf was explaining to me earlier was that the its custom to use return rather than console.log( ) with a function