Profile Lookup - So very close, except for Bob [SPOILERS][SOLVED]

I’m working on the Profile Lookup challenge and I have some code that fulfills all requirements except for returning “No such contact” when presented with “Bob”, “number”.

When I add a final else statement that I believe should solve this it instead breaks Kristian, Sherlock, and Harry.

Can someone take a look at my code and give me any advice as to what I’m missing here? Am I solving things out of order or is it sheer dumb luck this code works at all? :sob:

Thank you for any assistance~!

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

  for (var i = 0; i <= contacts.length; i++) {
    if (contacts[i].firstName == firstName) {
      if(contacts[i][prop]) {
        return contacts[i][prop];
      } else {
        return "No such property";
      }
    } 
/* everything but Bob works until I add this final else
   which then breaks Kristian, Sherlock, and Harry */
    else { 
      return "No such contact";
    }  
  }  
// Only change code above this line
}
7 Likes

When iterating through all elements in an array with a for-loop, it’s always i < length (not <=; that will exclude the last element).

Think about where return "No such contact" should appear in your code. It should only run after you have iterated through all of your contacts, and are sure there’s no such contact.

4 Likes

Hi @kevcomedia! Thank you so much for replying! Definitely the code that would evaluate and generate the “No such contact” was the issue. As is my MO I was overthinking/overcoding the solution when there was a much more graceful solution possible.

I’m confused by your explanation of comparison operators. It’s the opposite of my understanding of operators with i < length being “less than” and always one less and i <= length being “less than or equal to” which would include the last iteration of length…?

That said, either comparison operator seems to work in the solution I finally hit upon though it seems my .length - 1 must stay either way.

My code is below the spoiler alert.


:no_entry_sign::no_entry_sign::no_entry_sign: SPOILER ALERT :no_entry_sign::no_entry_sign::no_entry_sign:


Summary

function lookUpProfile(firstName, prop){

Summary

// Only change code below this line

Summary

for (var i = 0; i <= contacts.length; i++) {

Summary

if (contacts[i].firstName == firstName) {

Summary

if(contacts[i][prop]) {

Summary

return contacts[i][prop];

Summary

} else {

Summary

return “No such property”;

Summary

}

Summary

}

Summary

else if (i==contacts.length - 1) {

Summary

return “No such contact”;

Summary

}

Summary

}

Summary

// Only change code above this line

Summary

}

4 Likes

Remember that the index of the last element in an array is always length - 1. If you did i <= length, the loop will try to look for an element beyond the array’s range.

For example if you have ['apple', 'bamboo', 'cashew', 'durian'], which has length 4, its last element has index 3. If you iterated in a for-loop with i <= arr.length, it will loop until i = 4, then try to access index 4 in the array, which does not exist.

Hope this makes sense.

Oh, my bad, scratch this. I meant i will go out of bounds. Sorry for the confusion.


You can create spoilers in the editor. Click the gear icon, then hide details.

4 Likes

Hi, @kevcomedia and thanks again! I see now that the <= was returning “undefined” in my earlier attempts which was another thing driving me batty. Thanks for clearing that up and saving my sanity. ^_^;

The More You Know! :rainbow::star2:

1 Like

Thank you for posting this! I think the <= was preventing my loop from completing, so it never ran the final line in my code. Taking it out made my code work, and I’ve spent hours on this one…

function lookUpProfile(firstName, prop){
for (var i = 0; i < contacts.length; i++){
if (contacts[i].firstName == firstName) {
if (contacts[i].hasOwnProperty(prop) ){
return contacts[i][prop];
} else if (contacts[i].hasOwnProperty(prop) === false){
return “No such property”;
}
// I’ve being looking for this contacts.length - 1, thank you
}else if (i === contacts.length - 1 ){
return “No such contact”;
}
}

2 Likes

I piece together a couple of ideas together with some result but this help me out to completed successfully. thanks.:+1:

Challenge Profile Lookup

Hint: 1
Use a for loop to cycle through the contacts list.

try to solve the problem now

Hint: 2
Use a nested if statement to first check if the firstName matches, and then checks if the prop matches.

try to solve the problem now

Hint: 3

Leave your return “No such contact” out of the for loop as a final catch-all.

try to solve the problem now

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

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

What the difference betwen “=” and “==” in this problem. Why can´t we use just “=” like in “var i = 0”?

Hi, “=” assigns a value to a variable and “==” or “===” compares or checks to see if a parameter or variable is the same. Hope that helps!

I still have one question…

Why is this correct:

for (var n = 0; n < contacts.length; n++) {
    if (firstName == contacts[n].firstName) {
        var x = n;
        if (prop === "likes" || prop === "number" || prop === "lastName") {
            var value = contacts[x][prop];
            return value;
        }
        else {
            return "No such property";
        }
    }
  }
  
  return "No such contact";

But not this?

for (var n = 0; n < contacts.length; n++) {
    if (firstName == contacts[n].firstName) {
        var x = n;
        if (prop === "likes" || prop === "number" || prop === "lastName") {
            var value = contacts[x][prop];
            return value;
        }
        else {
            return "No such property";
        }
    }
    else {
        return "No such contact";
    }
  } 

When the only difference is the else statement being present inside the loop.

I thought every if statement should have an else “closing” statement.
So my question is this:

In what way and why does the else statement interfere with the function??

It’s not requisite that every if statement have an else closing statement; in this case, having the else closing statement inside the loop causes an early return – i.e., the loop will end on its first pass whether or not it can match the firstName property with the first object in the table array (if it does match, it proceeds with the nested if/else for prop; if it doesn’t match, it ends with “no such contact” and checks no further objects).

Putting the “no such contact” return outside the loop instead allows the loop to cycle thru the entire array unless it finds a match for firstName.

This threw me off for a bit as well.

4 Likes

wow thanks a lot.
Your answer really helped me understand better loops.

1 Like

I cleaned up your code.
You need to use triple backticks to post code to the forum.
See this post for details.

Ooops sorry. Thanks a lot

It seems like your code is very specific and not much general. Thus your solution would return error if someone added another property and asked about it. No problem here, but would not be scalable

1 Like

Here is my answer:

[details=Summary]
function lookUpProfile(firstName, prop){
// Only change code below this line
var result = “”;
/*
Don’t use ‘return’ in the if/else(s), it will stop the for loop looking beyond contacts[0]. E.g. contacts[1] and greater.

Using ‘break’ stops your loop when you found what property you are looking for in the Object or have not found any property whose name is included in ‘prop’.
*/
for(var i = 0; i < contacts.length; i++){
if(contacts[i].firstName === firstName){
if(contacts[i].hasOwnProperty(prop)){
// Make sure you do not do this:
// result = contacts[i].firstName[prop], it’s easy to get confused.
result = contacts[i][prop];
break;
}
else{
result = “No such property”;
break;
}
}
else {
result = “No such contact”;
}
}
return result;
// Only change code above this line
}[/details]

Wow, this has been giving me a lot of trouble, I was sure I hadn’t made any mistakes and I think it was something about writing return contacts[x].prop instead of contacts[x][prop]. I got the impression these were basically interchangeable, the lesson only mentions using brackets when there’s a space in it. What is the effective difference or rule for not using a dot here?

Hi and thanks for providing some great insight. The one thing I don’t understand about arrays is the term used, “length -1”. I know that arrays are indexed based starting from zero, but what does that term mean…a bit confused.