一些js数组去重的实现算法

  1. 双重循环法(最传统,理解简单)
javascript 复制代码
function unique(arr) {
  var result = [];
  for (var i = 0; i < arr.length; i++) {
    var flag = true;
    for (var j = 0; j < result.length; j++) {
      if (arr[i] === result[j]) {
        flag = false;
        break;
      }
    }
    if (flag) {
      result.push(arr[i]);
    }
  }
  return result;
}

var arr = [1, 2, 3, 2, 1];
console.log(unique(arr)); // [1, 2, 3]

原理

  • 外层遍历原数组每个元素,
  • 内层遍历结果数组检查是否已存在,
  • 没有就加入结果。

缺点:时间复杂度 O(n²),数组越大越慢。

  1. 利用 indexOf 去重(兼容 ES5)
javascript 复制代码
function unique(arr) {
  var result = [];
  for (var i = 0; i < arr.length; i++) {
    if (result.indexOf(arr[i]) === -1) {
      result.push(arr[i]);
    }
  }
  return result;
}

var arr = [1, 2, 3, 2, 1];
console.log(unique(arr)); // [1, 2, 3]

同样时间复杂度 O(n²),但代码更简洁。

  1. 利用对象做哈希表(更快的实现)
javascript 复制代码
function unique(arr) {
  var result = [];
  var seen = {};
  for (var i = 0; i < arr.length; i++) {
    if (!seen[arr[i]]) {
      result.push(arr[i]);
      seen[arr[i]] = true;
    }
  }
  return result;
}

var arr = [1, 2, 3, 2, 1];
console.log(unique(arr)); // [1, 2, 3]

注意

  • 这种方法对数字和字符串效果很好,时间复杂度接近 O(n)。
  • 对于对象或数组类型的元素,会转成字符串 [object Object],可能会出错。
  1. 使用 forEach 结合 indexOf(兼容 ES5)
javascript 复制代码
function unique(arr) {
  var result = [];
  arr.forEach(function(item) {
    if (result.indexOf(item) === -1) {
      result.push(item);
    }
  });
  return result;
}

var arr = [1, 2, 3, 2, 1];
console.log(unique(arr)); // [1, 2, 3]

简单的 ES6 写法:

  1. 使用 Set(推荐)
javascript 复制代码
let arr = [1, 2, 3, 2, 1];
let result = [...new Set(arr)];
console.log(result); // [1, 2, 3]

原理

  • Set 是一种集合结构,自动去掉重复值。... 展开运算符可以把它再变回数组。
  • 优点:简洁、可读性高
  • 缺点:不支持对象深度去重(引用类型的比较是地址)
  1. 使用 filter + indexOf
javascript 复制代码
let arr = [1, 2, 3, 2, 1];
let result = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(result); // [1, 2, 3]

原理

  • indexOf 会返回首次出现的索引,只有首次出现的位置和当前索引一致时才保留。
  • 缺点:每次 filter 内部都要遍历一次(O(n²))
  1. 使用 reduce + includes
javascript 复制代码
let arr = [1, 2, 3, 2, 1];
let result = arr.reduce((acc, cur) => {
  if (!acc.includes(cur)) acc.push(cur);
  return acc;
}, []);
console.log(result); // [1, 2, 3]

原理

  • reduce 逐个累加,includes 检查是否已存在。
  • 缺点:同样是 O(n²) 复杂度。
  1. 基于哈希表的去重(高效版)
javascript 复制代码
let arr = [1, 2, 3, 2, 1];
let seen = {};
let result = arr.filter(item => {
  if (!seen[item]) {
    seen[item] = true;
    return true;
  }
  return false;
});
console.log(result); // [1, 2, 3]

原理

  • 利用对象键的唯一性,O(n) 时间就能完成去重。
  • 优点:比 indexOf / includes 高效
  • 缺点:对象键会自动转成字符串({} 和 "[object Object]" 都会冲突),处理对象数组时要加序列化。
  1. 去重并排序
javascript 复制代码
let arr = [3, 1, 2, 3, 2, 1];
let result = [...new Set(arr)].sort((a, b) => a - b);
console.log(result); // [1, 2, 3]
  1. 对象数组去重(按某个字段)

假设有:

javascript 复制代码
let arr = [
  { id: 1, name: "A" },
  { id: 2, name: "B" },
  { id: 1, name: "C" }
];

按 id 去重:

javascript 复制代码
let seen = new Set();
let result = arr.filter(item => !seen.has(item.id) && seen.add(item.id));
console.log(result);
// [ { id: 1, name: "A" }, { id: 2, name: "B" } ]
相关推荐
Robot_Nav13 分钟前
TD3 —— 双延迟深度确定性策略梯度算法文献解读
算法·td3·drl
energy_DT14 分钟前
2026年十五五油气田智能增产装备数字孪生,CIMPro孪大师赋能“流动增产工厂”三维可视化管控
前端
斯维赤14 分钟前
每天学习一个小算法:归并排序
学习·算法·排序算法
龙猫里的小梅啊18 分钟前
CSS(四)CSS文本属性
前端·css
王老师青少年编程20 分钟前
csp信奥赛C++高频考点专项训练之贪心算法 --【区间贪心】:区间覆盖(加强版)
c++·算法·贪心·csp·信奥赛·区间贪心·区间覆盖(加强版)
陈皮糖..23 分钟前
27 届运维实习笔记|第三、四周:从流程熟练到故障排查,企业运维实战深化
运维·笔记·sql·nginx·ci/cd·云计算·jenkins
无巧不成书021824 分钟前
零基础Java网络编程全解:从核心概念到Socket实战,一文打通Java网络通信
java·开发语言·网络
MXN_小南学前端25 分钟前
watch详解:与computed 对比以及 Vue2 / Vue3 区别
前端·javascript·vue.js
碧海银沙音频科技研究院26 分钟前
杰理项目开发大全课程
人工智能·深度学习·算法
饭小猿人30 分钟前
Flutter实现底部动画弹窗有两种方式
开发语言·前端·flutter