JS数组去重的5种算法实现与兼容性处理
本文详细解析JavaScript中数组去重的五种常见实现方式,包括遍历法、对象键值对法、下标判断法、排序相邻法及优化遍历法。重点对比各方法的执行速度与内存占用,并针对IE8及以下浏览器不支持ECMAScript 5 indexOf方法的问题,提供兼容代码实现,帮助开发者根据场景选择最优方案。
JS数组去重的5种算法实现与兼容性处理
第一种方法是遍历数组法,这是最基础的去重思路。具体实现为创建一个新数组,遍历原始数组中的每个元素,如果该元素不在新数组中,则将其添加进去。需要注意的是,判断元素是否存在主要依赖“indexOf”方法,这是ECMAScript 5标准引入的特性。在IE8及更早版本的浏览器中,该方法不被支持,因此若需兼容低版本浏览器,必须额外编写兼容代码。
// 最简单数组去重法
function unique1(array){
var n = []; //一个新的临时数组
//遍历当前数组
for(var i = 0; i < array.length; i++){
//如果当前数组的第i已经保存进了临时数组,那么跳过,
//否则把当前项push到临时数组里面
if (n.indexOf(array[i]) == -1) n.push(array[i]);
}
return n;
}
第二种方法是对象键值对法,其执行速度在所有方法中通常最快,但代价是占用较多的内存空间,属于以空间换时间的策略。实现逻辑是构建一个JS对象和一个新数组,遍历原数组时,检查当前值是否已作为对象的键存在。若不存在,则将该值设为对象的键并加入新数组。此方法的一个潜在问题是,对象键会自动调用“toString()”进行转换,导致数字1和字符串“1”可能被误判为相同键。若要解决此类类型混淆问题,仍需结合“indexOf”进行额外判断。
// 速度最快, 占空间最多(空间换时间)
function unique2(array){
var n = {}, r = [], len = array.length, val, type;
for (var i = 0; i < array.length; i++) {
val = array[i];
type = typeof val;
if (!n[val]) {
n[val] = [type];
r.push(val);
} else if (n[val].indexOf(type) < 0) {
n[val].push(type);
r.push(val);
}
}
return r;
}
第三种方法是数组下标判断法,其性能表现与方法1相近,同样依赖“indexOf”。实现思路是:遍历数组时,检查当前第i项在当前数组中首次出现的位置索引是否等于i。如果首次出现的位置不是i,说明该项是重复元素,直接忽略;否则,将其存入结果数组。
function unique3(array){
var n = [array[0]]; //结果数组
//从第二项开始遍历
for(var i = 1; i < array.length; i++) {
//如果当前数组的第i项在当前数组中第一次出现的位置不是i,
//那么表示第i项是重复的,忽略掉。否则存入结果数组
if (array.indexOf(array[i]) == i) n.push(array[i]);
}
return n;
}
第四种方法是排序后相邻去除法。尽管原生数组的“sort”方法默认排序结果可能不符合数值大小预期,但在不严格要求顺序的去重场景中,这一缺点可以忽略。实现步骤为:首先对传入数组进行排序,使相同值相邻,然后遍历排序后的数组,仅将与前一个值不同的元素加入新数组。
// 将相同的值相邻,然后遍历去除重复值
function unique4(array){
array.sort();
var re=[array[0]];
for(var i = 1; i < array.length; i++){
if( array[i] !== re[re.length-1]){
re.push(array[i]);
}
}
return re;
}
第五种方法是优化遍历数组法,其代码实现较为精简高效。核心思路是获取每个元素最后一次出现的位置,并将其放入新数组。具体逻辑为:当检测到当前元素与后续元素重复时,终止当前内层循环并进入外层循环的下一轮判断,从而只保留最右侧的那个唯一值。此方法被推荐为较优方案。
// 思路:获取没重复的最右一值放入新数组
function unique5(array){
var r = [];
for(var i = 0, l = array.length; i < l; i++) {
for(var j = i + 1; j < l; j++)
if (array[i] === array[j]) j = ++i;
r.push(array[i]);
}
return r;
}
针对IE8及以下浏览器(仅支持部分ECMAScript 5标准)不支持“indexOf”方法的情况,需要手动扩展Array原型以提供兼容支持。
if (!Array.prototype.indexOf){
// 新增indexOf方法
Array.prototype.indexOf = function(item){
var result = -1, a_item = null;
if (this.length == 0){
return result;
}
for(var i = 0, len = this.length; i < len; i++){
a_item = this[i];
if (a_item === item){
result = i;
break;
}
}
return result;
}
}
综上所述,以上五种JS数组去重的算法实现各有优劣,开发者可根据具体性能需求和环境兼容性要求选择合适的方法,希望这些内容能对学习有所帮助。
JS动态构建复杂嵌套JSON对象的方法
2026-11-05 15:41:52
JS负数取余为什么是负数?详解余数与模运算区别
2026-11-05 13:34:41
JS 解压出现乱码或报错怎么解决?
2026-11-05 12:32:38
JS 中 startsWith、indexOf 与正则判断字符串前缀的对比
2026-11-04 22:19:43
JS解析Excel后怎么将数据转换为JSON格式
2026-11-04 20:58:28
