比较并将正确的值推送到 JavaScript/TypeScript 中的对象数组

Posted

技术标签:

【中文标题】比较并将正确的值推送到 JavaScript/TypeScript 中的对象数组【英文标题】:Compare and push the right value to Array of objects in JavaScript/TypeScript 【发布时间】:2019-03-22 06:28:33 【问题描述】:

以下两个问题看起来相似,但与我的算法无关。因为我面临的问题是相当困难的。没有一个解决方案可以帮助我。所以,我不得不发布一个很长的描述性问题来寻求一些指导。

    Comparing Two Arrays of Objects

    Comparing Two arrays Before pushing

我有两个看起来像的数组对象

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' 
]

我必须找到userRolesuserIdgroupId是否属于userList。所以我使用了下面的过滤方法

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

上面的方法是过滤我的两个对象并给我一个result 对象。像这样的东西。

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' 
]

我找到了各个用户的角色。现在,我必须将匹配用户的角色分配到userList = [] 对象中。如果任何特定用户没有该角色,则角色属性应为空。

所以我尝试使用下面的代码

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

不幸的是,我的第一个问题就是从这里开始的。因为result 始终为真,它映射数组角色列表并分配给usersList 对象我userRoles 对象中的所有角色。像这样的

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'] 
]

但我的结果应该是这样的

 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' 
    ]

还有我的第二个问题。假设我是属于两个组(g1, g2) 的用户(u2)。在g1 我是adming2 user。因此,我是g1 中的admin,我将获取属于g1 组的所有users。然后,我是g2 组的user,所以我将只获取角色仅为admin 的那些用户。所以我也做了一种方法。

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

所以现在我得到了满足这两个条件的过滤器 groupId。一个是,我是否属于那个群体,另一个是角色是什么。

所以现在我根据组ID做了一个循环并尝试获取所有userName,就像这样

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


然后我检查了其他组。如果是“用户”,我在该组中的角色是什么,那么我将获取groupID 以及循环finalUserlist 对象,然后获取角色仅为admin 的用户。像这样。

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

现在我得到了角色用户的过滤器 groupId。现在我将获取用户名。我使用了下面的代码。

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)
    
 

结果应该看起来像

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' 
    ]

这是我制作的一种非常繁琐的编码风格,这是完全错误的。请指导我降低算法复杂性并解决我的问题。 谢谢

【问题讨论】:

您正在映射所有用户及其角色,因此是数组。为什么不简单地遍历所有用户并添加额外的角色属性? @FortyTwo 感谢您的回复。你的意思是在这个检查if (result) this._usersList.map(e =&gt; e['roles'] = this._usersRoles.map(r =&gt; r.userRoles) ); 但是如果我做循环那么我怎么检查用户ID? 【参考方案1】:

您可以为所有角色构建一个Map,并使用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; 

【讨论】:

哇,你是救生员。非常感谢,请你看看我下面的问题。 那是我不明白的部分。输入是什么,结果应该是什么? 好的,抱歉我的描述模糊。我试图再次解释。你得到了 FinaluserList 对象。现在我必须实现以下算法。对于那个假设,我的用户 ID 是 u2。 1. 我必须检查我属于多少个组。 (在 FinaluserList 对象中,我属于两个组(g1,g2)。然后我会检查我的角色是什么。2。我的角色是组 g1 的管理员。和 g2 的用户。现在我将使用我的 groupID。 3.然后,我是管理员,我将获取该组的所有用户名。所以我的结果应该是获取属于g1的所有用户。因为我是g1的管理员 以及算法的第二部分。我必须检查我的其他角色,比如用户。例如。在组 g2 中,我的角色是 FinalUserList 对象中的用户。所以现在,我将在我作为用户的地方使用我的组 ID。然后我将获取属于同一组的所有用户,即 g2。我也会检查那些用户的角色。他们是管理员还是用户。如果他们是管理员,那么我将只获取这些用户。 如果我无法解释,请告诉我,我会再试一次

以上是关于比较并将正确的值推送到 JavaScript/TypeScript 中的对象数组的主要内容,如果未能解决你的问题,请参考以下文章

比较 2 个对象的值并将值推送到一个对象数组

以空格为分隔符的爆炸数组并将值推送到新数组

有没有更好的方法将值推送到表单控件,其中数组作为 Angular 中的值

如何遍历一组 Firebase Firestore 文档并将值推送到数组中

将Observable中的值推送到Observable

如何在 PHP 中将数组值推送到另一个数组中? [复制]