JavaScript 数字数组重复项计数查找时counter返回空问题排查
数字数组重复统计场景下counter返回空的问题解决
实际运行异常表现
- 字符串数组场景下原有逻辑可正常运行:输入文本拆分后,最终返回重复元素列表
["as", "i", "do"],对应计数对象{i: 2, do: 2, as: 3},完全符合预期。 - 复用相同逻辑处理数字数组时,重复元素列表
[9, 4, 7]可正常获取,但最终返回的计数对象为{},未保留任何元素的统计值。
异常根因
本质是类型不匹配导致的过滤逻辑完全失效:
- JavaScript普通对象的键名会被强制转为字符串类型:无论你用数字、布尔值还是其他类型做对象键,实际存储时都会被转成字符串。比如给
counter赋值counter[9] = 3,最终对象里实际存储的键是字符串"9",这也是Object.keys(counter)拿到的键值全部为字符串格式的原因。 - 原代码中
duplicates数组存储的是遍历数字数组时拿到的原生数字类型元素,没有做类型转换。 - 过滤逻辑执行时,是拿字符串类型的键(如
"9")和数字类型的duplicates元素(如数字9)做includes严格相等判断:由于"9" === 9结果恒为false,!duplicates.includes(key)的判断永远为真,导致counter里的所有键都被判定为“非重复元素”、全部被删除,最终返回空对象。
修正实现
只需要在匹配前统一两边的类型即可,无需大幅修改原有逻辑:
var arr = [9, 9, 9, 111, 2, 3, 4, 4, 5, 7, 7]; function CheckDuplicates(targetArr) { let counter = {}; let duplicates = []; for (let i = 0; i < targetArr.length; i++) { let item = targetArr[i]; counter[item] = counter[item] >= 1 ? counter[item] += 1 : 1; if (item !== "") { if (counter[item] == 2) { duplicates.push(item); } } } Object.keys(counter) // 统一转字符串类型后再做匹配,解决类型不匹配问题 .filter(key => !duplicates.map(item => String(item)).includes(key)) .forEach(k => delete counter[k]); return { duplicates: duplicates, counter: counter }; } let r = CheckDuplicates(arr); // 修正后实际输出: // duplicates: [9, 4, 7] // counter: {9: 3, 4: 2, 7: 2}
代码可优化点
- 修正原有逻辑的入参引用问题:数字数组场景下原函数形参命名为
sentence,但循环内直接引用全局变量arr,传入其他数组时会出现逻辑偏差,建议将循环内的数组引用替换为形参对应的入参值。 - 空值判断可做兼容:将
item != ""调整为item !== undefined && item !== null && item !== "",避免遍历到空值时出现统计偏差。
内容的提问来源于stack exchange,提问作者sdsd
相关产品推荐
相关产品推荐

