前言
数组去重是面试当中经常谈论的热点问题,在这里自己总结一下。
实现方法
1、双重for循环
双重for(or while)循环实际上是比较复杂的去重方法,比较笨拙,它的时间复杂度是O(n²),它的实现原理是:首先定义一个空数组,然后将原数组进行遍历,在循环中定义一个中间值去记录新数组中是否有重复数据的最终结果,有重复值数据,直接跳出里层循环继续进行比较,没有则添加到新的数组中,返回新数组。
let arr = [33,22,33,44,55,66,77,88,33,33,33];
function unique(arr) {
//提前判断是否是数组类型
if(!Array.isArray(arr)) {
console.log("type error!");
return;
}
//进入正题
let arrW = [];
for(let i = 0; i < arr.length; i++) {
let isUnique = true;
for(let j = 0; j < arrW.length; j++) {
if(arrW[j] === arr[i]) {
isUnique = false;
//出现重复元素跳出此次循环
break;
}
}
if(isUnique) {
arrW.push(arr[i]);
}
}
return arrW;
}
2、indexOf方法
原理:判断新数组的元素里面是否存在原数组中的元素,若存在跳出此次循环,不存在将元素添加到新的数组中,返回新数组。
function unique(arr){
if(!Array.isArray(arr)){
console.log("type error");
return;
}
let arrW = [];
for(let i =0;i<arr.length;i++){
if(arrW.indexOf(arr[i]) > -1) continue;
arrW.push(arr[i]);
}
return arrW;
}
3、filter and indexOf方法---(借鉴他人,自己咩想到)
原理:filter筛选,判断数组中的元素是否与第一次出现的位置相等,若是不相等,则是重复元素
function unique(arr){
if(!Array.isArray(arr)){
console.log("type error");
return;
}
//filter:返回值是一个数组,只有当指定函数返回true时,相应的元素才会被包在该数组中
return arr.filter((el,index,self) => self.indexOf(el) === index)
}
4、相邻元素sort()方法---(不考虑元素顺序)
原理:判断是否与相邻元素相等,相等则跳出此次循环,不相等添加到新数组中
let arr = [33,22,33,44,55,66,77,88,9,8,3];
function unique(arr){
if(!Array.isArray(arr)){
console.log("type error");
return;
}
let arrW = [];
arr.sort();
for(let i=0;i<arr.length;i++){
if(arr[i] === arr[i+1]) continue;
arrW.push(arr[i])
}
return arrW;
}
5、利用对象属性,并且可以统计出重复元素次数
function unique(arr){
if(!Array.isArray(arr)){
console.log("type error");
return;
}
let arrW=[],obj={};
for(let i=0;i<arr.length;i++){
if(!obj[arr[i]]){
arrW.push(arr[i]);
obj[arr[i]] = 1;
}else{
obj[arr[i]]++;
}
}
return arrW;
}
6、ES6 Set与解构赋值去重
function unique(arr){
if(!Array.isArray(arr)){
console.log("type error");
return;
}
return [...new Set(arr)]
}
7、ES6 Array.from与set去重
Array.from方法可以将Set结构转换为数组结果,而我们知道set结果是不重复的数据集,因此能够达到去重的目的
function unique(arr){
if(!Array.isArray(arr)){
console.log("type error");
return;
}
return Array.from(new Set(arr))
}
8、优化遍历数组法
function unique(arr){
if(!Array.isArray(arr)){
console.log("type error");
return;
}
var temp = [];
var index = [];
var l = arr.length;
for(var i = 0; i < l; i++) {
for(var j = i + 1; j < l; j++){
if (arr[i] === arr[j]){
i++;
j = i;
}
}
temp.push(arr[i]);
index.push(i);
}
return temp;
}
9、includes换indexOf
function unique(arr){
if(!Array.isArray(arr)){
console.log("type error");
return;
}
let arrW = [];
for(let i =0;i<arr.length;i++){
if(!arrW.includes(arr[i])) {
arrW.push(arr[i]);
}
}
return arrW ;
}
最后,ES7的includes方法,includes可以替换成indexOf,返回方法是boolean类型,这几种办法做了一下速度上的比较,后面数字是时间:
1、全部是整数的情况下,时间对比:
2、两位小数情况:
通过比较我们发现,es6 Set集合是最快的,但是我们要考虑兼容性问题。
优化改进有参照https://www.cnblogs.com/curationFE/p/js_array_duplication_removal.html
https://www.cnblogs.com/baiyangyuanzi/p/6726258.html