TenG
TenG

Reputation: 4004

Check Javascript nested obj value exists with unknown key

The following is used to build up a object array:

var users = {};

var user = {};
user[socket.id] = data.username;

if(users[data.roomname]){

   // Room already exists - check user already exists 

   // if data.username does not value exist is users then:

   users[data.roomname].push(user);
}
else{

   // New room

   users[data.roomname] = [user];
}

Over a few iterations we get something like this:

console.log ( 'Users: ', users );

users  { RoomABC:
   [ { YidwzgUHPHEGkQIPAAAD: 'Mr Chipps' },
     { 'JG-gtBMyPm0C1Hi1AAAF': 'Mr T' },
     { '2JFGMEdPbgjTgLGVAAAH': 'Mr Chipps' }, ] }

The issue is trying to ensure that each username is unique, so Mr Chipps should not be added again if that name already exists.

The examples I have seen Assume the keys are known. I have tried a number of things including some, indexOf but I am not able to get a simple 'does UserX already exist' to work.

The following is the latest block of code I tried to only add the user if not already present in the obj array. This works, but it seems very clunky to me; nested loops to get at the correct level to check the value and set a counter if a match found, then check the counter to decide if a match was found or not:

if(users[data.roomname]){

  // Room already exists - check user already exists 
                
  let found = 0;

  // Nested loop - seems a little clunky but it works

  Object.keys(users[data.roomname]).forEach(key => {

     Object.keys(users[data.roomname][key]).forEach(key2 => {

         if ( users[data.roomname][key][key2] === data.username ) {
            found++;
         }
     });
  });

  if ( found == 0 ) {
     users[data.roomname].push(user);
  }
}

I keep thinking surely there is neat one-liner that can do this check for the existence but I cant get any to work.

Upvotes: 1

Views: 395

Answers (1)

Nina Scholz
Nina Scholz

Reputation: 386578

You could check the values instead of using the keys and exit early if a name is found

if (users[data.roomname]) {
    if (!Object.values(users[data.roomname]).some(v => Object.values(v).some(n => n === data.username))) {
        users[data.roomname].push(user);
    }
}

Upvotes: 1

Related Questions