4
\$\begingroup\$

This is my answer in freecodecamp "Basic Javascript: Profile Lookup" (third day trying javascript using Udemy and freecodecamp).

My problem with the code is the huge number of lines on my lookUpProfile function. I would like to minimize the lines of code of my lookUpProfile function, can you suggest me ways to achieve that?

//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(firstName, prop){
// Only change code below this line

  var contain = 0;
  if(firstName == "Akira"){
    contain = 0;
    if(contacts[contain].firstName == firstName)
      if(contacts[contain].hasOwnProperty(prop))
        return contacts[contain][prop];
      else
        return "No such property";
    else
      return "No such contact";
  }
  else if(firstName == "Harry"){
    contain = 1;
    if(contacts[contain].firstName == firstName)
      if(contacts[contain].hasOwnProperty(prop))
        return contacts[contain][prop];
      else
        return "No such property";
    else
      return "No such contact";
  }  
  else if(firstName == "Sherlock"){
    contain = 2;
    if(contacts[contain].firstName == firstName)
      if(contacts[contain].hasOwnProperty(prop))
        return contacts[contain][prop];
      else
        return "No such property";
    else
      return "No such contact";
  }
  else if(firstName == "Kristian"){
    contain = 3;
    if(contacts[contain].firstName == firstName)
      if(contacts[contain].hasOwnProperty(prop))
        return contacts[contain][prop];
      else
        return "No such property";
    else
      return "No such contact";

  }
  else
    return "No such contact";


// Only change code above this line
}

// Change these values to test your function
lookUpProfile("Akira", "lastName");
\$\endgroup\$
4
  • \$\begingroup\$ Please include the exact problem description in your question so we can see the exact problem this code solves. \$\endgroup\$
    – Mast
    Jan 11 '17 at 8:23
  • \$\begingroup\$ pardon. my problem with the code is the huge number of lines on my lookUpProfile function any help I want to minimize the number of lines in the function? \$\endgroup\$ Jan 11 '17 at 8:30
  • \$\begingroup\$ No, I meant the problem description of the challenge, the assignment from FreeCodeCamp. \$\endgroup\$
    – Mast
    Jan 11 '17 at 9:14
  • 1
    \$\begingroup\$ Also, minimizing the amount of lines shouldn't be a goal in itself. Increasing readability and maintainability is much better. \$\endgroup\$
    – Mast
    Jan 11 '17 at 9:15
4
\$\begingroup\$

You have very repetitive code. This can be optimized. I'm not sure whether your function name lookUpProfile is the correct one, as you actually look up a property of a Contact and not its whole profile. But if the task is to look up a certain property of a Contact you can simplify the code to this:

function lookUpProfile(firstName, prop) {
    for (let contact of contacts) {  
        if (contact.firstName === firstName) {
            return contact[prop];
        }
    }
    return false;
}

How it works

It loops through all contacts:

for (let contact of contacts) {

It tests whether the firstName matches:

if (contact.firstName === firstName) {

In case a match is found it returns the requested property or undefined:

return contact[prop];

In case no match is found it returns false:

return false;

What it returns

This function will have a mixed return value. The code that is calling the function can now deal with the result. It will return one of the following:

  • false if no Contact with the requested firstName exists
  • undefined if a Contact matches but the requested property doesn't exists
  • string|array if a match was found and the property exists

So all those calls will work:

console.log(
    lookUpProfile(),
    lookUpProfile('A'),
    lookUpProfile('Sherlock'),
    lookUpProfile('Sherlock', 'number'),
    lookUpProfile('Kristian', 'likes')
);

The return values are:

false false undefined 0487345643 Array [ "Javascript", "Gaming", "Foxes" ]

What the code doesn't do:

It doesn't check whether there's a choice for Contacts, i.e. if more than one Contact with that name exists. It will always exit at the first match.

jsFiddle Demo

Try before buy


Update "No such property"

Regarding the OP's comment about a different return value, I would suggest keeping the code as is and let other parts worry about a concrete message:

var value = lookUpProfile('Sherlock', 'random');

if ('undefined' === typeof value) {
    console.log('No such property');
};

If your task is to include that text into the function you can replace this line:

return contact[prop];

with:

return 'undefined' === typeof contact[prop] ? 'No such property' : contact[prop];

This is a lot harder to handle, as the string "No such property" could be an actual value of a property.

\$\endgroup\$
2
  • \$\begingroup\$ hello.. one more thing, how about i want to display "No such property" string if the passed item is not a property of contacts lookup variable.. I tried to add else{return "No such property";} and its not working.. thanks. @insertusernamehere \$\endgroup\$ Jan 11 '17 at 11:05
  • 1
    \$\begingroup\$ @Vadamadafaka I've updated the answer. Hope it helps. \$\endgroup\$ Jan 11 '17 at 12:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.