前言
JS中数组去重是一个非常常见的问题,解决这个问题有好多种方法。面试时面试官也经常会问,你能不能写一个数组去重的办法呢?接下来我们就来聊聊JS中的数组去重问题。
方法
两层for循环
用for循环遍历数组,利用两层for循环一一进行比较,如果全等就用splice()剔除后面一个。代码如下:
let arr = [1, 1, '1', '1', 2, 2, 2, 3, 2]
function unique(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1)
//剪掉后后面的值向前走了一位,下标需要减一,避免少遍历一位
j--
}
}
}
return arr
}
这样去重虽然能解决问题,但是不太优雅,因为它改变了原数组,我们最好不改变原数组去完成数组去重的操作。
第一次优化
我们可以创建一个新数组,分别遍历原数组和这个新数组,拿空数组里面的值和原数组里面的值一一进行比较,如果原数组里面的值与空数组里面的值不全等,就用push方法将原数组里面的值加入到空数组中,如果全等,就用break跳出第二层循环。最后返回出这个新数组。
代码如下:
let arr = [1, 1, '1', '1', 2, 2, 2, 3, 2]
function unique(arr) {
let res = []
for (let i = 0; i < arr.length; i++) {
for (var j = 0; j < res.length; j++) {
//如果有全等就跳出循环
if (arr[i] === res[j]) {
break
}
}
//res全遍历完毕没有全等的
if (j === res.length) {
res.push(arr[i])
}
}
return res
}
console.log(unique(arr))
上述代码是比较直接来解决问题,兼容性较好,但是性能稍微差了点,时间复杂度较高。
第二次优化
这里我们用数组的一个方法indexOf()(一个用来查找数组元素的的方法,有的话会返回1,没有会返回-1),原理还是一样。
let arr = [1, 1, '1', '1', 2, 2, 2, 3, 2]
function unique(arr) {
let res = []
for (let i = 0; i < arr.length; i++) {
if (res.indexOf(arr[i]) === -1) {
res.push(arr[i])
}
}
return res
}
console.log(unique(arr))
上述代码indexOf()方法实际上也有一层循环,虽然时间复杂度没有改变,但是代码量变少了,简洁有效。
第三次优化
用ES6提供给我们的方法includes()(判断数组中是否具有某个值)。
let arr = [1, 1, '1', '1', 2, 2, 2, 3, 2]
function unique(arr) {
let res = []
for (let i = 0; i < arr.length; i++) {
if (!res.includes(arr[i])) {
res.push(arr[i])
}
}
return res
}
console.log(unique(arr))
这样也能解决去重的问题。
第四次优化
我们可以先将数组排一下序,先将第一个数装入数组,然后将后面一个数与前一个数进行比较,如果全等,后面的数就不往空数组里面装。代码如下:
let arr = [1, 1, '1', '1', 2, 2, 2, 3, 2]
function unique(arr) {
//解构创建一个新数组
let newArr = [...arr]
//数组进行排序
arr.sort((a, b) => a - b) //n*logn
let res = []
//定义一个变量记录上一次比较的值
let seen
for (let i = 0; i < newArr.length; i++) {
if (newArr[i] !== seen) {
res.push(newArr[i])
}
seen = newArr[i]
}
return res
}
console.log(unique(arr))
这样优化后时间复杂度就降低了,虽然sort()方法有循环,但是他们不嵌套,代码性能就变好了。
结语
以上就是数组去重问题的一些要点,通过这次学习我们应该能感受到对于一个问题通过代码解决其实有很多的办法,只不过有好有坏。我们应该学会将这些方法融汇贯通为自己所用,最后感谢观看。