今天记录下数组去重的几种方法,主要是思路。自觉在算法和数据结构方面比较薄弱,以后要注意这方面的学习。
1. 利用ES6的Set
ES6提供了一种新的数据结构Set,这种数据结构类似于数组,但是成员的值都是唯一的,不管是基本类型的值还是引用类型的值。学习更多关于Set的知识可以参考ECMAScript6入门一书。
Set是一个构造函数,它可以接受一个数组作为参数,返回的Set实例对象的成员都是唯一的。利用Array.from()
方法我们可以把Set对象转换为数组。所以通过Set这个“中转站”我们就达到了数组去重的目的。
1 | var arr = [1, 2, 3, 1, 2, 3] |
2. 使用includes或indexOf
1 | var arr = [1, 2, 3, 1, 2, 3] |
上面的代码先声明一个空数组作为最终要返回的结果数组,然后从数组头部遍历数组,判断当前遍历的项,如果结果数组中不存在该项,则push进结果数组,否则继续遍历。
3. 使用双层for循环嵌套,相同项删除
1 | var arr = [1, 2, 3, 1, 2, 3] |
这种方法的思路也是比较清晰的,两层for循环,判断两次for循环中当前遍历的项是否相等,如果相等,则用splice方法删除内层for循环的当前项。需要注意的几点是:(1)内层for循环的起始索引应该使用外层索引+1,因为相同的项不需要比较。(2)这里使用全等操作符===
来判断来个数组项是否重复是不够严谨的,首先NaN === NaN
返回的是false,判断NaN应该用isNaN()
方法;其次对象是否重复也要看具体要求,是要求对象的引用地址一致才算相同,还是说只要对象的属性一致就算相同要具体需求具体分析。在这里只是记录一下思路,就不做多余的判断了。(3)splice方法会修改原数组,所以最好像上面代码那样把输入函数的数组参数做一次拷贝。
4. 先排序然后相邻项比较
1 | var arr = [1, 2, 3, 1, 2, 3] |
这种方法的思路是先把原数组排序,排序后的数组,如果有重复项,那么重复项之间一定是相邻的,此时再遍历数组,只需要比较相邻项,相邻项不相同就把当前项push进预先定义的结果数组中,最后返回结果数组。
这里需要注意的是要比较的相邻项应该是array[i]
和array[i - 1]
而不是array[i]
和array[i + 1]
,因为array[i + 1]
已经超出数组的length范围了。相应的,遍历的起始索引也要从1开始,而不能从0开始,因为从0开始i - 1
就小于0了。还没完,起始索引从1开始,就意味着push这个动作也是从1开始的,所以要在遍历之前结果数组的初始化就应该包含数组索引0的项。