为何用于二维数组的去重函数会误删非重复元素?
问题分析与修复
原代码的核心问题
- 引用赋值篡改原数组:
let returnArr = arr是直接引用原数组,修改returnArr的同时会改变原数组,遍历过程中数组长度动态变化,导致逻辑混乱。 - 数组引用比较无效:
arrVal1 === arrValLoop比较的是数组对象的内存引用,只有同一个数组实例才会返回true,内容相同的不同数组实例会被判定为不相等,完全达不到去重目的。 - splice参数错误:
splice(arrVal1, 1)需要传入索引值,但你传了数组对象,会被转为NaN,相当于每次执行splice(0, 1),直接删除数组第一个元素,逻辑完全偏离需求。
修复后的代码
需求是保留每个数值+名称组合唯一的子数组,去除完全重复的项,以下是实现方案:
const scorersArr = [ [2, 'Lewandowski'], [1, 'Gnarby'], [2, 'Lewandowski'], [1, 'Hummels'], ] const returnNoDupes = (arr) => { const seen = new Set(); const result = []; for (const item of arr) { // 将子数组转为字符串作为唯一标识 const key = JSON.stringify(item); if (!seen.has(key)) { seen.add(key); result.push(item); } } return result; } console.log(returnNoDupes(scorersArr)); // 输出: [[2, "Lewandowski"], [1, "Gnarby"], [1, "Hummels"]]
关键逻辑说明
- 用
Set存储已出现的子数组字符串标识,确保每个组合只被记录一次。 - 把数组转为JSON字符串(数组是对象,直接比较引用不可靠),通过
Set判断是否重复,不重复则加入结果数组。 - 全程操作新数组,不会修改原数组,避免遍历过程中数组结构变化引发的问题。
如果你的需求是仅保留数值唯一的实例(即同一个数值只保留第一个出现的子数组),可以调整逻辑为只记录数值:
const returnNoDupes = (arr) => { const seenNums = new Set(); const result = []; for (const [num, name] of arr) { if (!seenNums.has(num)) { seenNums.add(num); result.push([num, name]); } } return result; } // 此时输出: [[2, "Lewandowski"], [1, "Gnarby"]]
内容的提问来源于stack exchange,提问作者user17259560
相关产品推荐
相关产品推荐

