2

Below two questions look similar but not relevant to my algorithm. Because the problem I faced is quite difficult. And None of the solutions could help me out. So that, I had to post a long descriptive question to seek some mentorships.

  1. Comparing Two Arrays of Objects

  2. Comparing Two arrays Before pushing

I have two array objects that look like

UsersList = [
0:{groupId: 'g1', userId: 'u1', userName: 'name1' }
1:{groupId: 'g1', userId: 'u2', userName: 'name2' }
2:{groupId: 'g1', userId: 'u3', userName: 'name3' }
3:{groupId: 'g1', userId: 'u4', userName: 'name4' }
4:{groupId: 'g2', userId: 'u2', userName: 'name2' }
5:{groupId: 'g2', userId: 'u5', userName: 'name5' }
6:{groupId: 'g2', userId: 'u6', userName: 'name6' }
7:{groupId: 'g2', userId: 'u7', userName: 'name7' }
8:{groupId: 'g2', userId: 'u8', userName: 'name8' }
]

userRoles = [
0:{groupId: 'g1', userId: 'u2', roles: 'admin' }
1:{groupId: 'g1', userId: 'u4', roles: 'admin' }
2:{groupId: 'g2', userId: 'u7', roles: 'user' }
3:{groupId: 'g2', userId: 'u5', roles: 'admin' }
4:{groupId: 'g2', userId: 'u2', roles: 'user' }
5:{groupId: 'g2', userId: 'u8', roles: 'admin' }
6:{groupId: 'g2', userId: 'u6', roles: 'admin' }
7:{groupId: 'g2', userId: 'u9', roles: 'admin' }
]

I have to find that the userId and groupId of userRoles belong to userList or not. So I used below filter method

const result = this._usersList.filter(e =>
  this._usersRoles.some(r => e.groupId === r.groupId && e.userID === r.userID  ) );

above method is filtering my two objects and giving me one result object. Something like this.

result = [
0:{groupId: 'g1', userId: 'u2', userName: 'name2' }
1:{groupId: 'g1', userId: 'u4', userName: 'name4' }
2:{groupId: 'g2', userId: 'u7', userName: 'name7' }
3:{groupId: 'g2', userId: 'u6', userName: 'name5' }
4:{groupId: 'g2', userId: 'u2', userName: 'name2' }
5:{groupId: 'g2', userId: 'u8', userName: 'name8' }
6:{groupId: 'g2', userId: 'u5', userName: 'name5' }
]

I found the roles of the individual users. Now, I have to assign roles for the matching users into the userList = [] object. If any particular user doesn't have the role then role property should be null.

So that I tried to use below code

if (result) {
  this._usersList.map(e => e['roles'] = this._usersRoles.map(r => r.userRoles) );
}

Unfortunately, My first problem began from here. Because the result is always true and it's mapping a list of array roles and assigned to usersList object all roles from my userRoles object. Something like this

UsersList = [
0:{groupId: 'g1', userId: 'u1', userName: 'name1', roles:['admin','admin','user','admin','user','admin','admin','admin'] }
1:{groupId: 'g1', userId: 'u2', userName: 'name2'  roles:['admin','admin','user','admin','user','admin','admin','admin'] }
2:{groupId: 'g1', userId: 'u3', userName: 'name3'  roles:['admin','admin','user','admin','user','admin','admin','admin'] }
3:{groupId: 'g1', userId: 'u4', userName: 'name4'  roles:['admin','admin','user','admin','user','admin','admin','admin'] }
4:{groupId: 'g2', userId: 'u2', userName: 'name2'  roles:['admin','admin','user','admin','user','admin','admin','admin'] }
5:{groupId: 'g2', userId: 'u5', userName: 'name5'  roles:['admin','admin','user','admin','user','admin','admin','admin'] }
6:{groupId: 'g2', userId: 'u6', userName: 'name6'  roles:['admin','admin','user','admin','user','admin','admin','admin'] }
7:{groupId: 'g2', userId: 'u7', userName: 'name7'  roles:['admin','admin','user','admin','user','admin','admin','admin'] }
8:{groupId: 'g2', userId: 'u8', userName: 'name8'  roles:['admin','admin','user','admin','user','admin','admin','admin'] }
]

But my result should look like this

 finalUsersList = [
    0:{groupId: 'g1', userId: 'u1', userName: 'name1', roles: null }
    1:{groupId: 'g1', userId: 'u2', userName: 'name2', roles: 'admin' }
    2:{groupId: 'g1', userId: 'u3', userName: 'name3', roles: null }
    3:{groupId: 'g1', userId: 'u4', userName: 'name4', roles: 'admin' }
    4:{groupId: 'g2', userId: 'u2', userName: 'name2', roles: 'user' }
    5:{groupId: 'g2', userId: 'u5', userName: 'name5', roles: 'admin' }
    6:{groupId: 'g2', userId: 'u6', userName: 'name6', roles: 'admin' }
    7:{groupId: 'g2', userId: 'u7', userName: 'name7', roles: 'user'}
    8:{groupId: 'g2', userId: 'u8', userName: 'name8', roles: 'admin' }
    ]

And my second problem. Suppose I am the user (u2) that belongs to two groups (g1, g2). In g1 I am the admin and in g2 user. Hence I am the admin of g1 I will fetch all users who belong to g1 group. And then, I am the user of g2 group, so I will fetch only those users whose roles are only admin. So that I did one method also.

if(myLocalStorageUserID === this._finalUsersList.filter(e => e.userId) && this._finalUsersList['roles'] == 'admin' {
const filterGroupIDForAdmin = this._finalUsersList['groupID ']
}

So Now I got the filter groupId that's fullfil the two conditions. One is, whether I am belongs to that group and other what the role is.

So Now I did one loop according to group Id and try to fetch the all usersName, Like this

for(let i=0; i<this.finalUserList.length; i++) {
if(this.finalUserList[i].groupId == filterGroupIDForAdmin ) {
const userListForWhoseRolesIsAdmin = []
userListForWhoseRolesIsAdmin.push(finalUserList[i].userName)
}
}

then I checked other groups. what is my role of that group if 'user' then I will take the groupID as well as and loop the finalUserlist object then fetch the users whose role is only admin. Like this.

if(myLocalStorageUserID === this._finalUsersList.filter(e => e.userId) && this._finalUsersList['roles'] == 'user' {
    const filterGroupIDForUser = this._finalUsersList['groupID ']
    }

Now I got the filter groupId for role user. And now I will fetch the usersname. I used below code.

for(let i=0; i<this.finalUserList.length; i++) {
    if(this.finalUserList[i].groupId == filterGroupIDForUser ) {
    const userListForWhoseRolesIsUser = []
    userListForWhoseRolesIsUser.push(finalUserList[i].userName , finalUserList[i].roles )
    }
    for(let i = 0; i<this.userListForWhoseRolesIsUser.length; i++) {
    const filterUserNameList =  []
    if(this.userListForWhoseRolesIsUser[i].role === 'admin') {
    filterUserNameList.push(userListForWhoseRolesIsUser[i].userName)
    }
 }

The Result should be look lik

finalUserName = [
    0:{groupId: 'g1', userId: 'u1', userName: 'name1', roles: null }
    1:{groupId: 'g1', userId: 'u2', userName: 'name2', roles: 'admin' }
    2:{groupId: 'g1', userId: 'u3', userName: 'name3', roles: null }
    3:{groupId: 'g1', userId: 'u4', userName: 'name4', roles: 'admin' }
    5:{groupId: 'g2', userId: 'u5', userName: 'name5', roles: 'admin' }
    6:{groupId: 'g2', userId: 'u6', userName: 'name6', roles: 'admin' }
    8:{groupId: 'g2', userId: 'u8', userName: 'name8', roles: 'admin' }
    ]

It's a huge cumbersome coding style that I made which is totally wrong. Please guide me to reduce my algorithm complexity as well as to solve my issue. Thanks

2
  • You are mapping all the users and their roles, hence the array. Why not simply loop through all the users and add an additional property of role? Commented Oct 17, 2018 at 14:36
  • @FortyTwo thanks for the reply. Do you mean in this checking if (result) { this._usersList.map(e => e['roles'] = this._usersRoles.map(r => r.userRoles) ); } But if I do loop then how can I check the userID ? Commented Oct 17, 2018 at 14:41

1 Answer 1

1

You could build a Map for all roles and map new objects with the role of roles.

function getUsers(user) {
    var groups = finalUsersList
            .filter(({ userId }) => user === userId)
            .reduce((r, { groupId, roles }) => (r[groupId] = roles, r), Object.create(null));

    return finalUsersList
        .filter(({ groupId, roles }) => 
            groups[groupId] === 'admin' ||
            groups[groupId] === 'user' && roles === 'admin'
        );
}

var usersList = [{ groupId: 'g1', userId: 'u1', userName: 'name1' }, { groupId: 'g1', userId: 'u2', userName: 'name2' }, { groupId: 'g1', userId: 'u3', userName: 'name3' }, { groupId: 'g1', userId: 'u4', userName: 'name4' }, { groupId: 'g2', userId: 'u2', userName: 'name2' }, { groupId: 'g2', userId: 'u5', userName: 'name5' }, { groupId: 'g2', userId: 'u6', userName: 'name6' }, { groupId: 'g2', userId: 'u7', userName: 'name7' }, { groupId: 'g2', userId: 'u8', userName: 'name8' }],
    userRoles = [{ groupId: 'g1', userId: 'u2', roles: 'admin' }, { groupId: 'g1', userId: 'u4', roles: 'admin' }, { groupId: 'g2', userId: 'u7', roles: 'user' }, { groupId: 'g2', userId: 'u5', roles: 'admin' }, { groupId: 'g2', userId: 'u2', roles: 'user' }, { groupId: 'g2', userId: 'u8', roles: 'admin' }, { groupId: 'g2', userId: 'u6', roles: 'admin' }, { groupId: 'g2', userId: 'u9', roles: 'admin' }],
    roles = userRoles.reduce(
        (m, { groupId, userId, roles }) => m.set([groupId, userId].join('|'), roles),
        new Map()
    ),
    finalUsersList = usersList.map(user => Object.assign(
        {},
        user,
        { roles: roles.get([user.groupId, user.userId].join('|')) || null }
    ));

console.log(finalUsersList);
console.log(getUsers('u2'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

17 Comments

Wow, You are the lifesaver. Thanks a lot, Could you please look at my below problem.
that is the part i do not understand. what is the input and what should be the outcome?
Ok, Sorry for my fuzzy description. I am trying to explain again. You got the FinaluserList Object. Now I have to implement below algorithms. For that Suppose, My user ID is u2. 1. I have to check how many groups I belong to. (In FinaluserList object I belong to two groups (g1, g2). Then I will check what is the roles of mine. 2. My role is admin for group g1. And user for g2. Now I will take the groupID of mine. 3. Then, where I am admin I will fetch the all username of that groups. So my result should be fetch all user who are belongs to g1. Because I am the admin of g1
And the second part of the algorithm. I have to check my other roles, like user. For example. In group g2 , My role is user in FinalUserList object. So now, I will take my group ID of mine where I am user. Then I will fetch all users, who are belongs to same group mean g2. and also I will check those users role. Are they are admin or user. If they are admin then I will fetch only those users.
Tell me if I couldn't explain then I will try again
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.