如何优化对象数组比对逻辑避免重复比对以查找重复项?
对象数组重复项查找优化方案
方案一:优化双层循环逻辑,消除重复比对
你原有代码的核心问题是内层循环起始位置不合理,导致每一对元素都会被正反比对两次。只需要调整内层循环的起始下标为i + 1,就可以保证每一对元素仅比对一次,同时也不需要再额外判断i === j的分支,还可以把外层循环的终止条件调整为i < array.length - 1,避免最后一个元素做无意义的遍历:
const handleArrayItems = () => { // 外层遍历到倒数第二个元素即可,最后一个元素没有后续元素可比对 for (let i = 0; i < array.length - 1; i++) { // 内层直接从i的下一个元素开始比对 for (let j = i + 1; j < array.length; j++) { if (_.isEqual(array[j],array[i])) { return true; } } } return false; };
该方案时间复杂度仍为O(n²),但比对次数直接减少一半,没有冗余计算。
方案二:单次遍历+哈希缓存,时间复杂度降至O(n)
如果数组长度较大,双层循环的性能瓶颈会比较明显。可以将对象转为稳定的哈希字符串存入Set做已访问标记,仅需一次遍历即可完成重复判断:
const handleArrayItems = () => { const visited = new Set(); for (const item of array) { // 先对对象键值对按key排序再序列化,避免对象键顺序不同导致的哈希不一致 const itemHash = JSON.stringify(Object.entries(item).sort()); if (visited.has(itemHash)) { return true; } visited.add(itemHash); } return false; };
如果你不想自己处理序列化逻辑,也可以直接用Lodash封装好的_.uniqWith方法,代码更简洁,Lodash内部已经做了性能优化:
const handleArrayItems = () => { // 用isEqual作为去重规则,去重后长度小于原数组长度说明存在重复项 return _.uniqWith(array, _.isEqual).length < array.length; };
内容的提问来源于stack exchange,提问作者programhur
相关产品推荐
相关产品推荐

