Basic Data Structures: Iterate Through the Keys of an Object with a for...in Statement

I’m having some trouble I guess understanding the for…in loop construct? I’m not sure why I can’t access the user’s online property with this code:


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

function countOnline(obj) {
  // change code below this line
  let counter = 0;
  for(let user in obj){
    if(user.online == true){
      counter += 1;
    }
  }
  // change code above this line
}

console.log(countOnline(users));

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-data-structures/-iterate-through-the-keys-of-an-object-with-a-for---in-statement

Finally figured it out. I think I need to further research bracket notation when accessing object properties. Can anyone expound on this topic helpfully? This was my solution:

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

function countOnline(obj) {
  // change code below this line
  let counter = 0;
  let user = '';
  for(user in obj){
    if(obj[user].online == true){
      counter += 1;
    }
    }
    return counter;
  }
  // change code above this line


console.log(countOnline(users));
2 Likes

This might be nitpicking, but you can write

if (obj[user].online == true){
  counter += 1;
}

as

obj[user].online && counter++;
1 Like

for...in iterates over the root properties of an object. This means that each property key is what is returned. Your confusion was in treating it like an array of users, where each index is the full object.

Since each property key is what’s being iterated, the value of user is the name property

/*
* user = Alan, Jeff, Sarah, Ryan
*/
for(let user in obj)

/*
* to access the actual user, we have to reference
* the variable. And we use have to use bracket notation 
* when using variables to access an object
*/
obj[user] // obj["Alan"]

You can always throw a console statement to see what’s being returned

for(let user in obj){
    console.log(user) // Alan, Jeff, Sarah, Ryan
    if(user.online === true){}
  }

Let me know if I didn’t make something clear

4 Likes

Thanks for the resources! It’s pretty straightforward after all

Hi Dan_Cio,

Just wanted to say thank you for sharing the other use of && and || that I never knew. After seeing your solution (and testing it…because I had to) I decided to go look up why it works. Pretty neat!

I just did

if (obj[user].online) counter++

Works just as well as far as I can tell, but your way is still neat! Here is my contribution to abbreviation (note, this is my solution below):

function countOnline(obj) {
let count = 0;
for (let user in obj) if (obj[user].online) count++;
return count;
}