JavaScript如何检查数组所有对象的指定属性以实现去重
代码失效原因定位
你写的去重判断逻辑存在语法层面的错误:!filtered_data.ID.includes(info.ID) 这行中,filtered_data 是存储对象的普通数组,它本身不存在名为ID的属性,因此调用filtered_data.ID拿到的是undefined,后续调用includes方法自然会报错,完全无法完成重复校验。
可行的去重实现方案
方案1:最小改动适配现有逻辑
只需要替换你原本的去重判断部分,不需要改动前面的筛选、合并逻辑:
//Remove duplicates temp_data.forEach((info) => { // 遍历已存结果数组,检查是否已存在相同ID的对象 const hasDuplicate = filtered_data.some(item => item.ID === info.ID) if (!hasDuplicate) { filtered_data.push(info); } });
这里用到的Array.some()方法会在遍历数组时,一旦找到第一个满足判断条件的元素就立即返回true,相比全量遍历的方式效率更高,非常适合做存在性校验。
方案2:更高效的Set去重(推荐数据量较大时使用)
当数据条数较多时,逐次遍历已存结果数组的写法会有O(n²)的时间复杂度,性能损耗比较明显。可以借助JS原生Set结构的特性,用单独的集合存储已经出现过的唯一ID,从根源上避免重复项写入,整体时间复杂度仅为O(n)。
你可以把原来零散的结果拼接、去重逻辑替换成以下代码:
function dataFilter() { // 每次执行筛选前先清空旧的结果,避免上次的留存数据污染本次结果 filtered_data = [] const seenIds = new Set() const hasAnyFilterChecked = document.getElementById("filter1-chkBox").checked || document.getElementById("filter2-chkBox").checked || document.getElementById("filter3-chkBox").checked || document.getElementById("filter4-chkBox").checked if (!hasAnyFilterChecked) { // 无筛选条件时直接返回全量数据,可根据业务逻辑调整 filtered_data = [...all_data] return } // 按勾选状态生成对应的筛选结果组 const resultGroups = [] if (document.getElementById("filter1-chkBox").checked) { resultGroups.push(all_data.filter(info => info.condition1 === true)) } if (document.getElementById("filter2-chkBox").checked) { resultGroups.push(all_data.filter(info => info.condition2 === true)) } if (document.getElementById("filter3-chkBox").checked) { resultGroups.push(all_data.filter(info => info.condition3 === true)) } if (document.getElementById("filter4-chkBox").checked) { resultGroups.push(all_data.filter(info => info.condition4 === true)) } // 统一遍历所有筛选结果,借助Set完成去重 resultGroups.forEach(group => { if (!group?.length) return group.forEach(item => { if (!seenIds.has(item.ID)) { seenIds.add(item.ID) filtered_data.push(item) } }) }) }
原有代码的几个容易踩的坑
- 原代码中直接将
temp_data初始化为temp_data_m,如果用户没有勾选第一个筛选框,temp_data_m会是上一次函数执行留存的全局变量值,容易出现旧数据混入本次结果的问题,最好在函数执行一开始就对所有临时变量做初始化清空 - 原
Data类的构造函数中第二个参数写为ame,但后续没有给类实例的对应属性赋值,如果后续需要用到对象名称属性,会出现取值为undefined的问题
内容的提问来源于stack exchange,提问作者Gekkouga
相关产品推荐
相关产品推荐

