如何基于ID比较两个对象数组并返回boolean类型的isModified状态
两个对象数组ID一致性校验实现方案
原代码问题说明
原代码无法正确执行的核心原因有两个:
- 校验逻辑错误:
initialArr.some((o2) => o2.id !== id)的判断规则是只要初始数组中存在任意一个ID不等于当前遍历ID就返回true,第一次遍历到id=8时,初始数组内的id=9就满足不等条件,直接触发break跳出循环,所以第二次循环永远不会执行 - 缺少长度校验:如果两个数组长度不一致(比如用户取消了某个选中项导致currentArr长度变短),现有逻辑完全无法识别这类修改
正确实现
实现思路
针对复选框选中集合的场景,不需要关心ID的排列顺序,只需要校验选中ID的集合是否完全匹配:
- 首先校验两个数组长度,长度不一致直接判定为已修改
- 将初始数组的所有ID存入Set,利用Set的O(1)查找效率提升校验性能
- 遍历当前数组的ID,只要存在一个ID不在初始ID集合中,就判定为已修改
修正后代码
function cancel() { const initialArr = [ {id: 8, name: "Celery", is_selected: 1}, {id: 9, name: "Crustaceans", is_selected: 1}, {id: 2, name: "Eggs", is_selected: 1}, {id: 6, name: "Fish", is_selected: 1}, ]; const currentArr = [ {id: 8, name: "Celery", is_selected: 1}, {id: 4, name: "Mustard", is_selected: 1}, {id: 2, name: "Eggs", is_selected: 1}, {id: 6, name: "Fish", is_selected: 1}, ]; // 长度不同直接判定为已修改 let isModified = initialArr.length !== currentArr.length; // 长度一致时再校验ID集合 if (!isModified) { const initialIdSet = new Set(initialArr.map(item => item.id)); isModified = currentArr.some(item => !initialIdSet.has(item.id)); } if(isModified){ alert('are you sure?'); } else { console.log('exit the page'); } }
兼容优化
如果需要兼容不支持Set的低版本运行环境,可以替换为数组includes实现,性能稍差但兼容性更好:
// 低版本兼容写法 if (!isModified) { const initialIds = initialArr.map(item => item.id); isModified = currentArr.some(item => !initialIds.includes(item.id)); }
内容的提问来源于stack exchange,提问作者RAHUL KUNDU
相关产品推荐
相关产品推荐

