Reputation: 329
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? ;).
Upvotes: 0
Views: 7581
Reputation: 1
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.
Upvotes: 0
Reputation: 105
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.
Upvotes: 2
Reputation: 17
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!
Upvotes: 1