Riyad
Riyad

Reputation: 377

Compare and push the right value to Array of objects in JavaScript/TypeScript

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

Upvotes: 2

Views: 376

Answers (1)

Nina Scholz
Nina Scholz

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

Related Questions