Comparison Operator Removes True Value in For Loop Iteration

I’ve spent hours trying to understand why this happens.

I’m trying to complete the Profile Lookup Challenge and I can satisfy all of the rules except for one. Which prioritizes the “No such contact” response over the “No such property” response when both parameters are not available.

I initially had the code to represent the "No such contact " response at the end of a loop, and it works but it does not satisfy the rules of the challenge, as it returns “No such property” in the event that both parameters are not available.

However when I try to reposition my the code that compares the name parameter to the for loop iteration, Whenever I use a prop parameter that is invalid, in the console.log() the == operator shows that the iteration is broken once the parameter entered is available and if I use the != operator it removes or skips the index of any valid parameter that’s entered from iteration.

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

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

var f = contacts[i].firstName;  //used f variable to represent first loop variable j
var  x;
var y = contacts[i].firstName;  // used y variable to iterate second loop variable i

 /*This initial IF statement always removes correct name property from iteration if != operator is used*/
if ( f != name) {
    console.log(f)
}

//This console.log shows that this IF statement in the for loop iterates correctly and does not break

if (y == name && contacts[i].hasOwnProperty(prop)) {     
       console.log(f)     
        x = contacts[i][prop]; 
    }  
    
     else if (contacts[i].hasOwnProperty(prop) == false) {

       x = 'No such property'; 
    }
} 

   return x;

  // Only change code above this line
}

console.log(lookUpProfile("Akira", "cat"));

Browser Information

Google Chrome
Version 92.0.4515.107 (Official Build) (64-bit)

Challenge:
Profile Lookup

Link to the challenge:

  1. if name AND property match return the property value
  2. else if name matches but property does not, return “No such property”
  3. otherwise (ie if name does not match at end of loop) return “No such contact”

You aren’t doing any of these: what you’re doing is storing your return value in a variable, so it gets overridden when the loop iterates to the next contact. With 1, you’ve got the condition but you aren’t returning. With 2, you’ve got half the condition, but you’re not returning. 3 isn’t there.

2 Likes

Hint: lookup continue statement.

Because once we know the contact firstName is different we want to ignore it

Mozilla Developer Network - continue statement

Just else would do, doesn’t need continue (all the if block at the start is doing is logging, it doesn’t remove anything), but that still doesn’t fix the main issue. Just using return is much simpler.

2 Likes

I have used continue statements, but its rare when I find them to be the cleanest way to express the logic. In general I find that they are best avoided.

2 Likes

I suppose it depends on whether you prefer “guard statements” or “conditional statements”

And procedural solution
for( ; ; ) for(in) for(of)

versus functional solution
map() filter() reduce()

Maybe? I’m not sure what you mean about that.

I try to be clear in my code and personally I’ve find jumping around due to continue or goto to generally be harder logic for others to follow.

Procedural vs functional doesn’t really have anything to do with my general preference to avoid continue statements.

In the context of the original question, the challenge requires that the function return specific values when certain conditions are met. I would make the solution match that requested behavior - return if conditions are met.

Hi, Dan I was only using return initially however return was causing the loop to break even after I placed it outside of the for loop I ended up with three return statements which still gave me a problem.

I’m not sure if that makes sense storing the return in a variable was my version of a “solution”

I’m not sure if that makes sense

With this overwriting though, you are only getting the result from the last entry in the contacts array.

Think carefully about the three requirements:

  1. If name is an actual contact’s firstName and the given property ( prop ) is a property of that contact, then return the “value” of that property.

  2. If prop does not correspond to any valid properties of a contact found to match name then return the string No such property .

  3. If name does not correspond to any contacts then return the string No such contact .

If you find a matching name, then you should return right away, but if the first name in the array of contacts doesn’t match, does that mean that no contact matches? Your code stops as soon as it hits a return statement. When can you say that no name matches?

1 Like

Ah, yes, what @JeremyLT says, I’ve made an assumption that there’s only one of each name (this is actually true in the case of the data you’re given but that’s by the by, you would want to store that there is a matching name but not a prop and return at the end rather than immediately). But you do want to return immediately if you hit a match, you do not want to immediately overwrite your match

1 Like

Interesting, the use of jumping around' implies use in embedded for( ;; )` loops, in which case I am with you.

I know nothing of these goto things you mention, apart from SEQ of course

You don’t need to use continue in a raw for loop. I prefer functional programming, but imperative code has its place. Sometimes it is a clearer and more efficient solution.

I really appreciate the help guys. I’ve only been coding a few days now so I’d just like you to bare with me a bit.

This isn’t the way I wrote it originally. I initially had it returning after a match. Without using a variable or any overwriting. But it always and still breaks whenever I use the != operator to compare and check the name value

even as it is with the overwriting it actually works it returns all of the contacts and the property that matches name. The problem comes in when I moved the of statement that compares name and returns ‘no such contact’ above the property

I can probably troubleshoot and come up with a way to pass the challenge but what I’d really like to understand is why my loop skips the iteration based on the value of (name, property) and the use of the comparison operators.


if ( f != name) {
    console.log(f)
‘No such contact’
}

That particular line of code was originally placed after the else if condition that returns ‘no such property’ but it doesn’t satisfy the challenge rule when I tried to place it before that property it acts really weird depending on the values of the parameters that’s why I ran a console.log() to check the output.

E.g. if I omit this line of code and run console.log (f) it iterates normally with
0 1 2 3 with and the parameters Sherlock and number gives the appropriate property value

However when i Include that code if I set parameters to Akira and cat console.log(f) would not iterate it only shows the index of the name property Akira it seems like in the absence of an existing property value it breaks or something like that

I’m really interested in it’s behavior and what about my code is causing it to behave that way

This isn’t valid syntax. Can you show us the full code you were using?

I’m not sure if any of this is making sense.

Maybe I’m overthinking it I’ll have to practice expressing myself in a more succinct manner as well I guess


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

if (contacts[i].firstName != name) {
    console.log(f)

 x = ‘No such contact’
}

I originally had it to return ‘No such contact’ but changed it to that when I started using the x variable to store the outputs

But at this point it would always return no such contact. Even though Akira is a contact because it sticks on the Akira index

This breaks my for loop if I input something like Akira and cats in my parameters

All of the variables and stuff are just a result of my trying to trick it into working

I need your full code. This on its own will not function.

This is still invalid syntax. I do not know what this line is supposed to do.

Sorry I’m using my phone forgive me

I’ll edit it

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

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

var f = contacts[i].firstName; //used f variable to represent first loop variable j
var x;
var y = contacts[i].firstName; // used y variable to iterate second loop variable i

/This initial IF statement always removes correct name property from iteration if != operator is used/
if ( f != name) {
console.log(f)
X = ‘No such contact’
}

//This console.log shows that this IF statement in the for loop iterates correctly and does not break

if (y == name && contacts[i].hasOwnProperty(prop)) {
console.log(f)
x = contacts[i][prop];
}

 else if (contacts[i].hasOwnProperty(prop) == false) {

   x = 'No such property'; 
}

}

return x;

// Only change code above this line
}

console.log(lookUpProfile(“Akira”, “cat”));

The behavior of the console.log(f) when you change the parameters is what’s perplexing to me

When I use Akira and bikes as the parameters it returns no such contact

While the console.log removes the index that includes Akira