8/8 Victory


#1

So the final page asks how you could format the output. Using these forums and some intuition, I've come come up with the following code....which seems to work. My issue being that I can only search one name at a time rather than multiple eg. search("Steve", "Bill"). Is this right or have I written something incorrectly that's stopping this? Thank you.

var friends = {
steve: {
firstName: "Bill",
lastName: "Gates",
number: "(206) 555-5555",
address: ["One Microsoft Way", "Redmond", "WA", "98052"],
},
bill: {
firstName: "Steve",
lastName: "Jobs",
number: "(206) 666-6666",
address: ["One Apple Way", "Greenmond", "AW", "98210"],
},
};

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

var search = function (name) {
for (var j in friends) {
if (name === friends[j].firstName) {
var log = "";
log += "\nFirst Name: " + friends[j].firstName;
log += "\nLast Name : " + friends[j].lastName;
log += "\nNumber : " + friends[j].number;
log += "\nAddress : " + friends[j].address[0];
log += "\n " + friends[j].address.splice(1).join(', ');
console.log(log);
}
}
};
list(friends);
search("Steve");


#2

Imitation is the best form of flattery. Glad you liked my method. I would go one step further though and reduce code bloat slightly:

var obj = friends[j];
var log = "";
log += "\nFirst Name: " + obj.firstName;

and so on.

To make the search function look for more than one name will require a considerable amount of code. Easier to search for one name at a time. Now if you were to search for either first or last or both, that would make your search function more powerful, but again, more code, more complexity. Worth the effort, though, if you have the time.


#3

Thank you! Yours was the method that seemed to make sense to me logically, I could follow it through and see what it was meant to be doing.

As long as I know that it's not meant to be able to search multiple names I will be able to sleep happy, I thought I had just messed it up.

Thank you for all the help...on wards and upwards!


#4

Actually one...not so much question, but confirmation. Am I right in saying that the var obj that you used there, because it is within a function it cant be called upon outside of it, so therefore doesn't really matter that it has a fairly generic name? It's sole purpose is to act within that function and nowhere else.


#5

It can be called outside if your remove var from the declaration,

obj = friends[j];

That will hoist it to global scope. Not really a good idea, though because it may destroy an obj that already exists in global scope. In a closure it would have a safe environment. Defining the friends object with a constructor would give it that. See below...

I like to use generic names inside functions and loop constructs, and more specific names otherwise. Not really big on over verbosity though, so probably cheat a little and stick to short as possible.

We need to future think, and remember a page can have many plug-ins all vying for the same space and resources. We might know what OUR script does, but how is it affected by others, and what effect does it have on others. A return value is better in most cases.

A friends object constructor:

function Contacts(name){
    this.name = name;
}
var friends = new Contacts('Friends');

Now the friends object has a custom class that it can inherit from. We can write all the methods in the prototype of the Contacts class and friends can access them.

Now we need a way to add a new contact to our friends object. Let's start building a prototype object for Contacts.

(function(){
    var Contact = function (first, last, phone, address) {
        this.firstName = first;
        this.lastName = last;
        this.phoneNumber = phone;
        this.address = address;
    };
    this.getName = function () {
        return this.name;
    };
    this.addContact = function (id,f,l,p,a) {
        this[id.toString()] = new Contact(f,l,p,a);
    };
    this.list = function (){
        obj = this;
        for (var key in obj) {
            if (typeof(obj[key]) !== 'function') {
                console.log(key);
            }            
        }        
    };
    this.search = function (name) {
        obj = this;
        for (var key in obj) {
            if (name === obj[key].firstName) {
                this.print(obj[key]);
            }
        }
    };
    this.print = function (obj) {
        var log = "";
        log += "\nFirst Name: " + obj.firstName;
        log += "\nLast Name : " + obj.lastName;
        log += "\nNumber    : " + obj.phoneNumber;
        log += "\nAddress   : " + obj.address[0];
        log += "\n            " + obj.address.splice(1).join(', ');
        console.log(log);
    };
}).call(Contacts.prototype);

Usage

 > friends.addContact('bill','Bill','Gates','(206) 555-5555',["One Microsoft Way", "Redmond", "WA", "98052"])
 > friends.search("Bill")

First Name: Bill
Last Name : Gates
Number    : (206) 555-5555
Address   : One Microsoft Way
            Redmond, WA, 98052

Hope this doesn't throw you for too much of a curve. It does go a little over the top and if the concepts are foreign it doesn't help to understand what is going on here.