0

I have an array of objects and I want to iterate over them. One object of this array looks like this:

var people = [
{
    "firstName": "YYY",
    "lastName": "XXX",
    "number": "123456789",
    "attribute": ["strong", "quick", "stupid"]
},
{
    "firstName": "AAA",
    "lastName": "BBB",
    "number": "9876543210",
    "attribute": ["calm", "wise", "slow"]
},
{
    "firstName": "CCC",
    "lastName": "VVV",
    "number": "158974528",
    "attribute": ["brutal", "bad", "gentle"]
}

and so on (around 20 objects in array).

And so on. I try to write a function which checks if the firstName exists in my people array and if the property is attribute of that contact. So if I call the function with attributes:

lookUpProfile("YYY", "lastName");

It should return me the value of attribute of this object. In that case: ["strong", "quick", "stupid"]

What it actually does is that my function checks only the first object and then stops...So it works only if i call this function with arguments which matches the first object in array. If I call the function like this:

lookUpProfile("CCC", "number");

It returns me "No Such contact". What's wrong here so the loop checks only the first object?

Here is the code of function:

function lookUpProfile(firstName, attribute){
   for (i = 0; i < people.length; i++) {
      if (firstName == people[i].firstName && firstName == people[i].firstName) {
         return (people[i][attribute]); 
      }      
      else {
        return "No such contact";
    }
   }

Thanks for all reply! It helps a lot. But I forgot to mention about one thing. I want also to check if the given property (attribute) exists in object.

So if I call the function lookUpProfile("YYY", "YourAGE"); It shall return me "No such property";

My function looks now like this:

function lookUpProfile(firstName, prop){
   for (i = 0; i < people.length; i++) {
      if (firstName == people[i].firstName && people[i].hasOwnProperty(prop))  
        return (people[i][prop]); 
      else if(firstName != people[i].firstName) {
        return "No such contact";
      }
      else if(people[i].hasOwnProperty(attribute) == false) {
        return "No such property";
      }
      
  }

return "No such contact";

Thanks You all! I got the working solution. Last question: can You explain only this line: if (firstName == people[i].firstName) firstNameFound = true;? I don't understand this line - why is the variable called after IF statement? ;).

3
  • What happens if the condition (which checks the same thing twice O.o) in the if ( ... ) isn't fulfilled? What's the purpose of the keyword return? Commented Mar 10, 2018 at 15:45
  • 1
    "In that case: ["strong", "quick", "stupid"]" should be "In that case: "XXX"" Commented Mar 10, 2018 at 15:49
  • It was a Typo in my code. The proper one is given on the bottom of my post :). So: If the firstName is an object's name and the object has property given in function, it shall return the property. If the firstName does not exist in array - return shall be "No such contact". If the propoerty does not exist in object - return "No such property". Commented Mar 10, 2018 at 16:09

3 Answers 3

2

What happens here is that a return statement causes the function to exit at the point where it is reached. As such, after the first instance of the loop, since the condition is not satisfied the if-else block returns and the function execution ends.

What you want to do here is return "no such contact" after the loop is done and every check has been executed. As such:

function lookUpProfile(firstName, attribute){
    for (i = 0; i < people.length; i++) {
        if (firstName == people[i].firstName && firstName == people[i].firstName) {
            return (people[i][attribute]); 
        }      
    }
    return "No such contact";
}

This code will execute the loop, checking each person in the array for the condition. If any of them match it returns, otherwise it returns after they have all been checked.

Edit: Since you need your final return statement to be conditioned, you will want to use the else block to set a flag that identifies which condition wasn't met:

function lookUpProfile(firstName, prop) {
    var firstNameFound = false;
    for (i = 0; i < people.length; i++) {
        if (firstName == people[i].firstName && prop == people[i].hasOwnProperty(prop)) {
            return (people[i][prop]);
        } 
        else {
            if (firstName == people[i].firstName) firstNameFound = true;
        }
    }
    if (firstNameFound) return "No such property";
    else return "No such contact";
}

Edit 2: Only a single flag is needed here. If the loop finished and it is set, we can assume that the second condition fails, as the name is tested first.

Edit 3: Fixed a couple mistakes. Here's a working JSFiddle with the same code as above: https://jsfiddle.net/bfhev7gL/16/

Edit 4: To answer your last question about the second if line, the variable (which was formerly assigned false during initialization) is assigned the value true if the check for first name existing is met. As the result of this conditional can be resolved in a single line, we can simply append the line after it without the need to wrap it in braces.

At the end of the loop, we can affirm that if it is assigned then at least one firstName matched, but since the loop finished and did not return then prop did not match when firstName did. Then we can condition the error return around it; if firstName matched we inform the user that prop did not, otherwise firstName wasn't found to begin with and we can inform the user of that instead.

Sign up to request clarification or add additional context in comments.

2 Comments

@icelandico Then edit your question and add this information.
Almost! It still does not return "No such property" when the wrong property is given.
1

It's works only for first value because you are returning the control from else statement. You should be using else return statement outsite of for loop to work and remove else statement from for loop.

Thanks!

Comments

0

All explanations are correct, but here's a simpler way to write this code:

function lookUpProfile(name, attribute) {
    for (let i = 0; i < people.length; i++) {
        if (people[i].firstName == name) {
            if (people[i].hasOwnProperty(attribute)) {
                return people[i][attribute];
            }else return "No such property";
        }
    }return "No such contact"
};

I changed the name of the first function parameter to name to avoid a little confusion, as firstName is also used in the object

by not using && and instead nesting two if statements, we can avoid setting flags altogether. The second if statement only evaluates if the first one is true (if a name is found). It is important to have return "No such contact outside of the for loop and not outside the first if statement, as it allows the function to continue looping through people until a condition is met, and if it is not met return "no such contact". if it is placed inside the loop after the first if statement, the loop will terminate and return "no such contact" after the first iteration if a name isn't found.

you can actually simplify this even further

function lookUpProfile(name, attribute){
    for (let i = 0; i < people.length; i++){
        if (people[i].firstName == name){
            return people[i][attribute] || "no such property";
        }
    }return "no such name";
};

using the || operator in our first return statement, we can eliminate the second if statement.

if a name is found but the attribute does not exist, return people[i][attribute] will return undefined. || basically states that if the statement to the left of || is undefined, return whatever is on the right.

second block of code not written by me, taken from a freeCodeCamp course.

please correct me if I'm wrong on anything, I'm still learning.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.