Profile Lookup [Spoilers] [Solved]

I have a problem with this challenge, my first if statement stops working when the other two are present. Here’s my code:

//Setup
var contacts = [
{
“firstName”: “Akira”,
“lastName”: “Laine”,
“number”: “0543236543”,
“likes”: [“Pizza”, “Coding”, “Brownie Points”]
},
{
“firstName”: “Harry”,
“lastName”: “Potter”,
“number”: “0994372684”,
“likes”: [“Hogwarts”, “Magic”, “Hagrid”]
},
{
“firstName”: “Sherlock”,
“lastName”: “Holmes”,
“number”: “0487345643”,
“likes”: [“Intriguing Cases”, “Violin”]
},
{
“firstName”: “Kristian”,
“lastName”: “Vos”,
“number”: “unknown”,
“likes”: [“Javascript”, “Gaming”, “Foxes”]
}
];

function lookUpProfile(firstName, prop) {
// Only change code below this line
for (var i = 0; i < contacts.length; i++) {

if (contacts[i].firstName == firstName && contacts[i].hasOwnProperty(prop)) {
return contacts[i][prop];
}

else if (contacts[i].firstName != firstName) {
return “No such contact”;
}

else if (contacts[i].hasOwnProperty(prop) === false) {
return “No such property”;
}

}
// Only change code above this line
}

// Change these values to test your function
lookUpProfile(“Kristian”, “lastName”);

^ when I call this function it returns “No such contact”. Any idea why this is happening?

Then it’s time for debug a bit?

Put before last return:

console.log(contacts[i].firstName);
console.log(contacts[i].hasOwnProperty(prop));

return "No such contact";

run and look into console:

"Akira"
true
"No such contact"

So now you have clue where it fails. Time for examine code logic:

if (contacts[i].firstName == firstName && contacts[i].hasOwnProperty(prop))

So far so good, Akira isn’t Kristian, though, there is a property “likes”. Then it goes to:

} else if (contacts[i].firstName != firstName) {

Wait. You already checked that Akira isn’t Kristian, - so now - if Akira isn’t Kristian:

return "No such contact";

Recheck logic again, and feel free to ask if you don’t understand something.

3 Likes

I’m confused here, I thought that in Javascript once the “for” loop hits the “if” statement that is true and returns something the loop starts over instead of going further. I’m not sure how to solve this problem without using three different “for” loops, which seems rather redundant and a bad practice.

It’s all fine. We all learning here.

Actually, you confusing “return” (which basically exiting from function with some return) and “break” - which interrupting loops.

Now you can use “break”, if you wish to interrupt your “for” loop. At least make it work, doesn’t matter how ugly it will be!

I’m still not sure how to do this, appearently when I use “break” inside my “if” statement after “return” it’s ignored and interpreter jumps to the next “if” statement. Seems like I can use only “return” or “break” inside a single “if” statement, both just won’t work.

Actually, algorithm is simpler than you trying to do. You just lost in your a bit complex if-else structure.

Try that idea:

You already have perfect loop for it, it goes through all the records. Wipe out everything from inside and just leave that “for” structure, filled like:

for (var i = 0; i < contacts.length; i++){
    if (WE GOT RIGHT NAME){
      if (WE GOT RIGHT PROP) {
        return GUESS WHAT?;
      } else {
        return GUESS WHAT?;
      }
    }
} // END OF FOR
return "YOU STILL NEED GUESS THIS TOO!";

Maybe this will be less confusing, see - just two IF’s and one ELSE.

16 Likes

This challenge was really difficult for me, and this thread helped me get past part of it (Thank you MK-61!) while the rest came from doing research on using Javascript functions with if /else statements and returns. What I came up with does not seem elegant, but it worked and “Kool-Aid man said Oh Yeah!” :slight_smile: . As you can see below, I ended up using two different “for-loops.” Surely it is possible to do this without two loops?

Here is my code:

function lookUpProfile(firstName, prop) {
for (i = 0; i < contacts.length; i++) {
if (contacts[i].firstName === firstName) {
if (contacts[i].hasOwnProperty(prop)) {
return contacts[i][prop];
}
}
}
for (i = 0; i < contacts.length; i++) {
if (contacts[i].firstName !== firstName) {
return “No such contact”;
} else {
return “No such property”;
}
}
}

1 Like

This one took me a while but i ended up piecing together a solution. Pretty ugly i know, but it got the job done.

function lookUpProfile(firstName, prop){

  var names = [];

  for (var j = 0; j < contacts.length;j++){
    names += contacts[j][0];}

  for (var i=0; i < contacts.length; i++){
    if(contacts[i].firstName == firstName){
      if(contacts[i].hasOwnProperty(prop)){
      return contacts[i][prop];
      } else {
        return "No such property";
      }
    } 
  } 
  if (!names.hasOwnProperty(firstName)){
    return "No such contact";
  }
 }
2 Likes

Some good solutions. Here’s how I did it:

function lookUpProfile(firstName, prop){
var ourContact = contacts.filter(function(contact){
  return contact.firstName === firstName;
});
  if(!ourContact[0]) return "No such contact";
  else if (!ourContact[0].hasOwnProperty(prop)) return "No such property";
  else return ourContact[0][prop];
}
4 Likes

Thanks MK-61!

I had the logic, but I was struggling with finding the right method and still learning the JavaScript Object syntax. Your algorithm example help me recognize I had the logic down and just needed to focus on syntax. Thanks so much for you help!!

Another possible solution:

function lookUpProfile(firstName, prop){
// Only change code below this line

  for (var i = 0; i < contacts.length; i++) {
    if (contacts[i].firstName === firstName) {
      if (typeof(contacts[i][prop]) != "undefined") {
        return contacts[i][prop];
      }
      else {
        return "No such property";
      }
    }
  }
  return "No such contact";
   
// Only change code above this line
}

I cheated a little by using typeof and undefined to see if the property exists.

– Jay

3 Likes

After solving this problem with a For loop, I realized I wasn’t quite satisfied with my answer because what I really wanted to tell the function to do was to check through all the first names listed in the contacts list, and if it gets to the end of the contacts list with no matches THEN it should say there were no matches.

Since I couldn’t determine how to do this with a For loop, I decided that a While loop may be the way to go since I would have a bit more flexibility on when it would execute the code for increasing i by one to check the next object, and also when I would finally tell it to call off the search for a matching contact and say that there isn’t one. Since in debugging I realized I wouldn’t know when the function would finally find a match for the first name, I needed the flexibility of when it would execute certain parts of the code. This post https://www.codecademy.com/en/forum_questions/510e3c1a3011b8fa25005255 really helps explain when to use a While loop vs a For loop.

tl;dr a While loop gives you enough flexibility in your search so you do not have to run into the issue of it returning “No such contact” for each time the contact[i].firstName != firstName.

3 Likes

Here is my soluction

    if(contacts[i].firstName === firstName){
      if(contacts[i].hasOwnProperty(prop) === true){
        return contacts[i][prop];
      }
      else if(contacts[i].firstName === firstName || 
              contact[i].hasOwnProperty(prop) === false){
        return "No such property";
      }
    }
    }
        return "No such contact";
```
7 Likes

Hi Guys,

I also had a bit of difficulty where I was returning a premature result without looping through the whole array. My final solution is below. It may be a little cumbersome but I got there eventually:

function lookUpProfile(firstName, prop){
// Only change code below this line
  
  var error;
  
  for (i = 0; i < contacts.length; i++) {
    
    if (firstName === contacts[i].firstName && contacts[i].hasOwnProperty(prop)) {
      return contacts[i][prop];
    }
    
    if (firstName !== contacts[i].firstName) {
      error = "No such contact";
    }
    
    if (!contacts[i][prop]) {
      error = "No such property";
    }
  }
   
    return error;
  
// Only change code above this line
}

// Change these values to test your function
lookUpProfile("Sherlock", "lastName");
1 Like

Hi. This is my solution after some refinements.

function lookUpProfile(firstName, prop){
// Only change code below this line
  for (var pi = 0; pi < contacts.length; pi++) {
    if (contacts[pi].firstName != firstName) continue;
    
    return contacts[pi][prop] ? contacts[pi][prop] : 'No such property';
  }
  
  return 'No such contact';
// Only change code above this line
}
2 Likes

Here is my solution

function lookUpProfile(firstName, prop){

      for(i = 0; i < contacts.length; i++) {
        if(firstName === contacts[i].firstName) {
          if(contacts[i].hasOwnProperty(prop)) { 
             return contacts[i][prop];
          } else {
             return "No such property";    
          }
        } // *
      }
         return "No such contact";
    }

Initially I had this line return "No such contact"; where I have marked with *.
This didn’t work, but made sense to me because it came after the “if” statement for checking firstName against contacts[i].firstName. Can someone explain why the above solution works?

3 Likes

Just try write on the paper what happens with your variables at each step - it will be more clear. Now, if you put your return “No such contact” inside the loop, it just will not iterate through all possible names (if first name in contacts is not the same as the name value it is checking against it then will return “No contact” terminating the loop). You need to check against all names in your contacts, so you need the loop to run all iterations. In your decision you put it outside of the loop, so it works. In this case, if the name is in contacts list, another return statement will run and the program will not get to your “No such contact” return statement. Just understand that return makes it to go out of the function - after return runs, no other code in the function will run.

4 Likes

Thank you for that explanation. Very helpful :+1:

Just did this one and it was tricky - and I had the last return in the wrong place too at first- keeping track of open and closed brackets is always an issue.

I wish FCC would introduce the concept of pseudocode as it’s really helpful in a situation like this even if pseudocode isn’t exactly intuitive to everyone

The solution for this challenge is deceptively simple, and needs only 1 loop. I’ll put my solution in pseudocode:

for i = 0 to size of 'contacts'
    if firstName in object
        if prop in object
            return property
        else
            return property not found
return contact not in list // note this is outside & after the loop

(edited to remove unneeded boolean variable)

3 Likes