Profile Lookup logic partially flawed

Tell us what’s happening:

Your code so far


//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(name, prop){
// Only change code below this line
var i = contacts.length;
var count =0;
do {
  var msg = "No such contact";
  if (contacts[count].firstName == name && contacts[count].hasOwnProperty(prop)){
  msg = contacts[count][prop];
  count ++;
  }
  else if (!contacts[count].hasOwnProperty(prop)) msg = "No such property";
  count ++;
}while(count < i);
return msg;
// Only change code above this line
}

// Change these values to test your function
lookUpProfile("Akira", "likes");

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36.

Hi all, am in need of some pointers with regards to my code logic. While it is able to iterate through the input, its not giving the right output which passes the test and i have tried picturing my code logic several times to no avail trying to figure out the which part of my code logic went wrong.
TIA

else if (!contacts[count].hasOwnProperty(prop))

This will set the msg variable even if the contact name does not match.

In addition to what @ArielLeslie said, in the above test case, you should not iterate passed the first contact before returning [“Pizza”, “Coding”, “Brownie Points”]. There is no reason to keep checking other objects once you have assigned either a property value or “No such property” to msg.

Dear all, based on your inputs i have restructured my code to the following:

function lookUpProfile(name, prop){
// Only change code below this line
var i = contacts.length;
var count =0;
do {
  var msg = "No such contact";
    if (contacts[count].firstName == name && contacts[count].hasOwnProperty(prop)){
    msg = contacts[count][prop];
   
    }
    else if (!contacts[count].hasOwnProperty(prop)) {
    msg = "No such property";

    }
    else
    count ++;
}while(count < i);
return msg;

However it seems just asArielLeslie has said that line of code is setting the msg variable even if the contact name doesnt match. At this point im slightly lost and have tried to resolve it by myself to noavail, apologies in advance but i may need additional pointers.

@quekyt Let me walk you through what is going on in your current code attempt above.

If we take the example test case of lookUpProfile("Akira", "likes"); when you enter the do loop, you assign “No such contact” to msg. Next you check if the first contact object’s firstName property has a value equal to “Akira” and if this same contact object has a property named “likes”. It so happens that this first if statement evaluates to true, so you assign msg the value ["Pizza", "Coding", "Brownie Points"]. At this point, you really should be returning the current value of msg as you have actually met the following instructions requirement:

The function should check if name is an actual contact’s firstName and the given property ( prop ) is a property of that contact.

If both are true, then return the “value” of that property.

Unfortunately, you reach the end of the do…while loop and the condition of count < 1 is evaluated. Since count is still 0 and i is 4, the loop starts over and you assign msg the value “No such contact” again. Also, the same if statement will evaluate to true again and then you will keep repeating this forever (infinite loop). You have several issues going on here.

  1. You are not exiting the loop and returning the correct value once you have assigned to msg.
  2. Even if the first object’s firstName property did not match the name or the the object did not have a property equal to prop, your do…while loop would never move to the other objects, because you only would do so if both the if and the else if evaluated to false.
  3. You need to think about when it really makes to most sense to assign msg the value “No such contact”. You can figure that out by answering the question in the following scenario.

Let’s say I give you a list of names on a piece of paper and tell you to look down the list and tell me if you find the name xyz. Let’s assume you start at the top of the list and go to the bottom of the list looking for the name xyx. At what point during your search could you conclude 100% that the name is NOT on the list?

Thanks Randell, in essence i will need to break out of the if statement once the condition has been met am i right? Something like the below?

do {
    if (contacts[count].firstName == name && contacts[count].hasOwnProperty(prop)){
    msg = contacts[count][prop];
    count ++;
    break;
    }
    else if (!contacts[count].hasOwnProperty(prop)) {
    msg = "No such property";
    count++;
    break;
    }
    else{
    count ++;

    }
}while(count < i);
return msg;

This looks more promising. Instead of all those count++, why not just have a single count++ before the end of the do…while loop (after the if/else if/else). Also, do you really need the else statement? Did you figure out where to put the msg = "No such contact"?

Hi Randall, thanks for the pointer. I’m still trying to figure it out in my head where should i have declared the msg =“No such Contact”. Why couldn’t i declare the msg as a global variable and let that be the default state instead? So that if the do/while statement doesnt change the msg, by default it should output “No such contact”.

My revised code below:

function lookUpProfile(name, prop){
// Only change code below this line
var i = contacts.length;
var count =0;
var msg = "No such contact";

do {
  
    if (contacts[count].firstName == name && contacts[count].hasOwnProperty(prop)){
    msg = contacts[count][prop];
    break;
    }
    else if (!contacts[count].hasOwnProperty(prop)) {
    msg = "No such property";
    break;
    }
    count++;
}while(count < i);
return msg;
// Only change code above this line
}

That is exactly where I would put it based on your current logic. However, you still have the issue which @ArielLeslie pointed out several posts back regarding your else if statement’s logic. Once you resolve this, you will pass the challenge.

Thank you! English isn’t my native language thus i took awhile longer to figure it out.

My final output:

function lookUpProfile(name, prop){
// Only change code below this line
var i = contacts.length;
var count =0;
var msg = "No such contact";

do {
  
    if (contacts[count].firstName == name && contacts[count].hasOwnProperty(prop)){
    msg = contacts[count][prop];
    break;
    }
    else if (!contacts[count].hasOwnProperty(prop) && contacts[count].firstName == name) {
    msg = "No such property";
    break;
    }
    count++;
}while(count < i);
return msg;
// Only change code above this line
}

// Change these values to test your function
lookUpProfile("Akira", "likes");

Glad you figured it out.

Just one suggestion. Since you check contacts[count].firstName == name in both the if and else if statement, it would be better to just have a single if statement for just this part and then your if statement would just check contacts[count].hasOwnProperty(prop) and instead of an else if statement, you would simply have an else statement. Anytime you have duplicate code, it typically means you can refactor it to remove the duplicate part.

So the following:

if (contacts[count].firstName == name && contacts[count].hasOwnProperty(prop)) {
  msg = contacts[count][prop];
  break;
}
else if (!contacts[count].hasOwnProperty(prop) && contacts[count].firstName == name) {
  msg = "No such property";
  break;
}

becomes:

if (contacts[count].firstName == name) {
  if (contacts[count].hasOwnProperty(prop)) {
    msg = contacts[count][prop];
    break;
  }
  else {
    msg = "No such property";
    break;
  }
}

Is that not cleaner?

Agreed! Thanks for pointing it out and taking the time to craft an example. Will put more thought about it for my next assignment.