数组去重在面试和工作中都是比较容易见到的问题,在这里我们介绍一些数组去重的方法,和大家一起分享一下,如果有的地方不对,大家可以指出来,共同学习。
方法一:使用双重for循环
这个方法是非常经典的一个数组去重方式,使用比较方式,用数组的第一位和后一位进行比较,如果相等,则用splice方法删除掉当前一位;该方法虽然在大型数组去重的性能上面有一定缺陷,但是这个方法容易理解和应用,所以使用的人还是蛮多的。
思路:
- 双层循环,外层循环元素,内层循环时比较值
- 值相同时,则删去这个值
let arr = ['123', '123', 1,2,3,2,1, '哈哈','hah', '哈哈', 'bibi']
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
}
console.log(unique(arr), '第一种方法');
// 最终输出结果为:[ '123', 1, 2, 3, '哈哈', 'hah', 'bibi' ] '第一种方法'
优点:简单易懂,兼容性好!
缺点:占用内存高,速度慢
注意:
- 上述方法如果数组中有对象、NaN、数组时是无法正确去重的。
- 双重遍历的缺点是复杂度太高。
- 为了方便起见,下面用到的数组都是上面的数组
方法二:indexOf和includes
使用indexOf(),可以判断一个数组中是否包含某个值,如果存在则返回该元素在数组中的位置,如果不存在则返回-1。这里我们新建一个数组来保存去重后的数组,如果该数组不包含元素就将该元素push到该数组中。
// 方法二
function unique1(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(unique1(arr), '第二种方法')
// 使用includes()方法也可以判断数组是否包含某个特定的元素,如果包含就返回true不包含就返回false。这和indexOf()方法有些类似,所以我们使用includes()进行数组去重和indexOf()的方法原理是一样的。
function unique2(arr) {
let res = []
for (let i = 0; i < arr.length; i++) {
if (!res.includes(arr[i])) {
res.push(arr[i])
}
}
return res
}
console.log(unique2(arr), '第二种方法')
注意:在IE6-8下,数组的indexOf方法不存在
方法三: 使用filter
filter()方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。并且filter()不会改变数组,也不会对空数组进行检测。filter()方法接收一个回调函数。
语法:
arr.filter(function(item,index,arr), value)
这里我们用判断indexOf(item)判断当前元素的索引是否等于当前index,如果相等就返回该元素。
// 方法三
function unique3(arr) {
return arr.filter((item,index, arr) => {
return arr.indexOf(item) === index
})
}
console.log(unique3(arr), '第三种方法')
方法四:使用set
ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
// 方法四
function unique4(arr) {
return [...new Set(arr)]
}
console.log(unique4(arr), '第四种方法')
方法五:使用reduce
// 第五种方法
function unique5(arr) {
return arr.reduce((pre, cur) => {
!pre.includes(cur) && pre.push(cur)
return pre
}, [])
}
console.log(unique5(arr), '第五种方法')
方法六:创建对象形式
function unique6(arr) {
let obj = {}, ary = []
arr.map(function (item, index) {
if (obj[item] !== item) { //核心思想,比较
obj[item] = item;
ary.push(item)
}
})
return arr;
}
console.log(unique6(arr), '第六种方法');
注意:
该方法的核心思想和第一个方法是一样的,也是进行比较,不过采取的方式不一样,这个方法是事先创建了一个空数组和空对象,通过取对象的属性值来和数组的当前项比较,如果不存在则把数组的当前项存储到空数组里面去;因为这个方法是一层循环,所以它的性能是明显优于第一种方法。
总结:数组去重的方法主要是上面几种,其他的基本都是在此基础上扩展的。