Passing an Object in a Function

Viewed 260

I am doing a freecodecamp challenge and I am being asked to finish writing a function that returns true if the object passed contains all four names: 'Alan' 'Jeff' 'Ryan' 'Sarah'. an Object is defined earlier, containing the data :

let users = {
    Alan: {
      age: 27,
      online: true
    },
    Jeff: {
      age: 32,
      online: true
    },

etc. the function begins like this

function isEveryoneHere(userObj) {}

and I have this written as my completed function, in which I am able to return all 4 names:

for (const property in userObj) {
  if (userObj) {
    return userObj.hasOwnProperty(property)
  }

But I am still being told that I am not meeting the criteria of the challenge. Any pointers or tips of advice?

edit: Error Message The users object should not be accessed directly

Passed The users object should only contain the keys Alan, Jeff, Sarah, and Ryan

Passed The function isEveryoneHere should return true if Alan, Jeff, Sarah, and Ryan are properties on the object passed to it.

The function isEveryoneHere should return false if Alan is not a property on the object passed to it.

The function isEveryoneHere should return false if Jeff is not a property on the object passed to it.

The function isEveryoneHere should return false if Sarah is not a property on the object passed to it.

The function isEveryoneHere should return false if Ryan is not a property on the object passed to it

edit:

this is how they solved it

function isEveryoneHere(userObj) {
  if (
    userObj.hasOwnProperty("Alan") &&
    userObj.hasOwnProperty("Jeff") &&
    userObj.hasOwnProperty("Sarah") &&
    userObj.hasOwnProperty("Ryan")
  ) {
    return true;
  }
  return false;
}
4 Answers

I would probably do something like

let users = {
    Alan: {
      age: 27,
      online: true
    },
    Jeff: {
      age: 32,
      online: true
    },
}

function check(userObj) {
  return ['Alan', 'Jeff', 'Ryan', 'Sarah'].every(user => userObj.hasOwnProperty(user));
}

function check2(userObj) {
  return ['Alan', 'Jeff', 'Ryan', 'Sarah'].every(user => Object.keys(userObj).includes(user));
}

console.log('check: ' + check({ Jeff: 1, Alan: 2, Ryan: 3, Sarah: 4 }));
console.log('check2: ' + check2({ Jeff: 1, Alan: 2, Ryan: 3, Sarah: 4 }));
console.log('Should fail (check): ' + check(users));
console.log('Should fail (check2): ' + check2(users));

both variants should satisfy all criteria - except the one that the object should not be accessed directly. I am not sure what they mean by that, but the second one transforms the keys into an array, so maybe that's what they are looking for, even though it's inefficient.

Spec describes includes function as linear search. So when you use it in any loop then it will increase its worst-case time complexity to n * 2. If you need to check for the existence of a name then you can use Set here which is optimized for an existence check.

To make an optimized solution you can use Set here

let users = {
  Alan: {
    age: 27,
    online: true
  },
  Jeff: {
    age: 32,
    online: true
  },
  Sarah: {
    age: 48,
    online: true
  },
  Ryan: {
    age: 19,
    online: true
  }
};

function isEveryoneHere(userObj) {
  const nameDict = ['Alan', 'Jeff', 'Sarah', 'Ryan'];
  const keys = new Set(Object.keys(userObj));
  return nameDict.every(name => keys.has(name))
}

console.log(isEveryoneHere(users));

I ran this through the link and it passed

let users = {
  Alan: {
    age: 27,
    online: true
  },
  Jeff: {
    age: 32,
    online: true
  },
  Sarah: {
    age: 48,
    online: true
  },
  Ryan: {
    age: 19,
    online: true
  }
};

function isEveryoneHere(userObj) {
  const names = ['Alan', 'Jeff', 'Ryan', 'Sarah'];
  const keys = Object.keys(userObj);
  for (let name in names) {
    if (!(name in keys)) {
      return false;
    }
  }
  return true;
}

console.log(isEveryoneHere(users));

It loops through each name in names and checks if the users object contains a key that is equivalent to that name. If any name isn't in keys, it returns false. Otherwise, it returns true.

let users = {
  Alan: {
    age: 27,
    online: true
  },
  Jeff: {
    age: 32,
    online: true
  },
  Ryan: {
    age: 27,
    online: true
  },
  Sarah: {
    age: 32,
    online: true
  },
};
const myProps = ['Alan', 'Jeff', 'Sarah', 'Ryan'];

function isEveryoneHere(userObj, expectedProps) {
    return expectedProps.every(el => Object.keys(userObj).includes(el));
}

console.log(isEveryoneHere(users, myProps))

Posting this as the answer vs a comment.

Related