Reputation: 377
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.
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
Upvotes: 2
Views: 376
Reputation: 386610
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; }
Upvotes: 1