Karl
Karl

Reputation: 111

Problem when comparing JavaScript objects in an array

I have these 2 arrays of information. I want to resolve this problem: (Given the name of an user and a required permission, return true if the user have that permission and false otherwise.)

const groups = [
  {
    id: 1,
    name: 'admins',
    permissions: ['CREATE', 'DELETE', 'READ', 'WRITE'],
  },
  {
    id: 2,
    name: 'readers',
    permissions: ['READ'],
  },
  {
    id: 3,
    name: 'writers',
    permissions: ['WRITE'],
  },
  {
    id: 4,
    name: 'managers',
    permissions: ['CREATE', 'DELETE'],
  }
];

const users = [
  {
    name: 'john',
    groups: [1],
  },
  {
    name: 'mary',
    groups: [2, 3],
  },
  {
    name: 'alice',
    groups: [2]
  },
  {
    name: 'bob',
    groups: [3],
  },
  {
    name: 'eve',
    groups: [2, 4],
  },
];

the code I've written so far:

function userHasPermission(userName, requiredPermission) {
  //looping through first array
  for (i = 0; i < users.length; i++) {

    if (users[i].name === userName) {
        // looping through the second array
        for (j = 0; j < groups.length; j++) {

            //here I don't know how to resolve this comparison, because as far as I understand it, the script has to check if userName is a valid ID inside groups array?
            if (users[i].groups.includes(groups[j].id) && (groups[j].permissions.includes(requiredPermission))) {
                return true;
            } else {
                return false;
            }
        }
    }
  }  
  
};

  userHasPermission("mary", "WRITE");

I'm new to Vanilla JavaScript and I'm stuck at this point, any help will be appreciated!

Upvotes: 2

Views: 55

Answers (2)

Brendon
Brendon

Reputation: 24

function userHasPermission(userName, requiredPermission) {
     const user = users.find(u => u.name === userName);
     let result = false;

     user.groups.forEach(id => {
        const group = groups.find(g => g.id === id);
        result = group.permissions.includes(requiredPermission);
     });

     return result;
};

userHasPermission("mary", "WRITE");

Upvotes: 1

hackape
hackape

Reputation: 19947

function userHasPermission(userName, requiredPermission) {
  //looping through first array
  for (i = 0; i < users.length; i++) {

    if (users[i].name === userName) {
        // looping through the second array
        for (j = 0; j < groups.length; j++) {
            if (users[i].groups.includes(groups[j].id) && (groups[j].permissions.includes(requiredPermission))) {
                return true;
            } else {
                continue;  // don’t return false yet. 
            }
        }
    }
  }  
  // only when you’ve checked all possibilities
  // still find no match, now you can return definitely
  return false;
};

Above is imperative for-loop style based on your code. I personally prefer more functional code style. For your reference:

function userHasPermission(userName, requiredPermission) {
  const targetUser = users.find(user => user.name === userName);
  if (!targetUser) return false;
  
  const userGroups = groups.filter(g => targetUser.groups.includes(g.id));
  const permissions = userGroups.flatMap(g => g.permissions);
  
  return permissions.includes(requiredPermission);
}

Upvotes: 3

Related Questions