JS 数组去重
今天来聊一聊 JS 数组去重的一些方法, 包括一些网上看到的和自己总结的, 今天也把他们归纳起来吧. 我总结了 5 种方法(ES5), 还有一点就是, 我使用的 JS 编码风格是 JavaScript Standard 风格, 是不加分号的(避免给大家造成误会).
第一种: 遍历数组法
这种方法最简单最直观, 也最容易理解, 代码如下:
- var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2]
- var newArr = []
- for (var i = 0; i < arr.length; i++) {
- if (newArr.indexOf(arr[i]) === -1) {
- newArr.push(arr[i])
- }
- }
- console.log(newArr) // 结果:[2, 8, 5, 0, 6, 7]
这种方法很好理解, 利用了 indexOf()方法 (indexOf() 方法如果查询到则返回查询到的第一个结果在数组中的索引, 如果查询不到则返回 - 1). 先创建一个新的空数组用来存储新的去重的数组, 然后遍历 arr 数组, 在遍历过程中, 分别判断 newArr 数组里面是不是有遍历到的 arr 中的元素, 如果没有, 直接添加进 newArr 中, 如果已经有了(重复), 那么不操作, 那么从头到尾遍历一遍, 正好达到了去重的目的.
第二种: 数组下标判断法
这种方法也比较好理解, 代码如下:
- var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2]
- var newArr = []
- for (var i = 0; i < arr.length; i++) {
- if (arr.indexOf(arr[i]) === i) {
- newArr.push(arr[i])
- }
- }
- console.log(newArr) // 结果:[2, 8, 5, 0, 6, 7]
这和第一种方法有重叠, 不说多余的, 直接看 if 这里, 在遍历 arr 的过程中, 如果在 arr 数组里面找当前的值, 返回的索引等于当前的循环里面的 i 的话, 那么证明这个值是第一次出现, 所以推入到新数组里面, 如果后面又遍历到了一个出现过的值, 那也不会返回它的索引, indexof()方法只返回找到的第一个值的索引, 所以重复的都会被 pass 掉, 只出现一次的值都被存入新数组中, 也达到了去重的目的.
第三种: 排序后相邻去除法
这种方法用到了 sort()方法, 代码如下:
- var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2]
- arr.sort()
- var newArr = [arr[0]]
- for (var i = 1; i < arr.length; i++) {
- if (arr[i] !== newArr[newArr.length - 1]) {
- newArr.push(arr[i])
- }
- }
- console.log(newArr) // 结果:[0, 2, 5, 6, 7, 8]
这种方法的思路是: 先用 sort()方法把 arr 排序, 那么排完序后, 相同的一定是挨在一起的, 把它去掉就好了, 首先给新数组初始化一个 arr[0], 因为我们要用它和 arr 数组进行比较, 所以, for 循环里面 i 也是从 1 开始了, 我们让遍历到的 arr 中的值和新数组最后一位进行比较, 如果相等, 则 pass 掉, 不相等的, push 进来, 因为数组重新排序了, 重复的都挨在一起, 那么这就保证了重复的这几个值只有第一个会被 push 进来, 其余的都和新数组的被 push 进来的这个元素相等, 会被 pass 掉, 也达到了去重的效果.
第四种: 优化的遍历数组法
- var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2, 8]
- var newArr = []
- for (var i = 0; i < arr.length; i++) {
- for (var j = i + 1; j < arr.length; j++) {
- if (arr[i] === arr[j]) {
- i++
- j = i
- }
- }
- newArr.push(arr[i])
- }
- console.log(newArr) // 结果:[0, 5, 6, 7, 2, 8]
思路: 两层 for 循环, 外面一层是控制遍历到的前一个 arr 中的元素, 里面一层控制的是第一层访问到的元素后面的元素, 不断的从第 0 个开始, 让第 0 个和他后面的元素比较, 如果没有和这个元素相等的, 则证明没有重复, 推入到新数组中存储起来, 如果有和这个元素相等的, 则 pass 掉它, 直接进入下一次循环. 从第 1 个开始, 继续和它后面的元素进行比较, 同上进行, 一直循环到最后就是: 不重复的都被推入新数组里面了, 而重复的前面的元素被 pass 掉了, 只留下了最后面的一个元素, 这个时候也就不重复了, 则推入新数组, 过滤掉了所有重复的元素, 达到了去重的目的.
第五种: 数组遍历法
- var arr = ['a', 'a', 'b', 'c', 'b', 'd', 'e', 'a']
- var newArr = []
- for (var i = 0; i < arr.length; i++) {
- var bl = true
- for (var j = 0; j < newArr.length; j++) {
- if (arr[i] === newArr[j]) {
- bl = false
- break
- }
- }
- if (bl) {
- newArr.push(arr[i])
- }
- }
- console.log(newArr) // 结果:["a", "b", "c", "d", "e"]
思路: 也是两层 for 循环, 外层 for 循环控制的是 arr 数组的遍历, 内层 for 循环控制的是新数组的遍历, 从第 0 位开始, 如果新数组中没有这个 arr 数组中遍历到的这个元素, 那么状态变量 bl 的值还是 true, 那么自然进入到了 if 中把这个值推入到新数组中, 如果有这个元素, 那么代表重复, 则把状态变量 bl 取值改为 false, 并且跳出当前循环, 不会进入到 if 内部, 而进入下一次外层开始的循环. 这样循环往复, 最后也达到了去重的效果.
来源: https://juejin.im/post/5c6d63f751882562c955e714