ReactJS中如何通过对象数组过滤对象数组?
问题解决:对象数组过滤返回空数组的原因及修复方案
核心问题
你用includes判断对象是否存在于数组中时,比较的是对象的引用地址,而不是对象的内容。你通过map生成的permissionsOnRole和listOfAllPermissions里的对象都是全新的实例,哪怕内容完全一样,引用地址也不同,所以includes永远返回false,过滤结果自然是空数组。
修复方案
先把需要排除的权限名称提取成一个Set(查找效率更高),再用filter过滤掉这些名称对应的项,就能得到你要的结果:
const setUncheckPermissions = () => { // 生成角色已有的权限数组 const permissionsOnRole = role.permissions.map(it => ({name: it, isChecked: true})); // 生成所有权限数组 const listOfAllPermissions = props.permissions.map(permission => ({ name: permission.name, isChecked: true })); // 提取角色已有的权限名称到Set中 const existingPermissionNames = new Set(permissionsOnRole.map(p => p.name)); // 过滤掉已存在的权限,保留剩余项 const result = listOfAllPermissions.filter(item => !existingPermissionNames.has(item.name)); console.log(result); // 输出目标数组:[{name:'A',isChecked:true}, {name:'B',isChecked:true}] }
另一种写法(用some判断)
如果不想用Set,也可以用some方法逐个比对对象的name属性,但性能比Set略差(数组较大时明显):
const result = listOfAllPermissions.filter(item => !permissionsOnRole.some(p => p.name === item.name) );
关键说明
- 对象的引用比较:两个对象即使内容完全一致,只要不是同一个实例,
===和includes都会返回false。 - Set的优势:查找元素的时间复杂度是O(1),而
some是O(n),当数组元素较多时,Set的性能更优。
内容的提问来源于stack exchange,提问作者shinichirou ikebe
相关产品推荐
相关产品推荐

