基本情况:数组中存储的都是基本数据类型
方式一:
// ES5
let test = [1,2,3,1,3,5,2,4,6]
function unique( arr ) {
let res = arr.filter( function(item, index, array) {
return array.indexOf(item) === index
})
return res
}
console.log(unique(test))
方式二:
// ES6
let unique2 = arr => [...new Set(arr)]
console.log(unique2(test))
方式三:
// 算法实现
// 使用一个同向指针
function unique3( arr ) {
if(!arr || arr.length === 0) return []
arr.sort( (a,b) => a - b )
let i, j = 1
for(i = 0; i < arr.length; i++) {
while(j < arr.length && arr[j] === arr[i]){
j++
}
if(j >= arr.length)
break
arr[i + 1] = arr[j]
}
return arr.slice(0, i + 1)
}
console.log(unique3(test));
方式四:一种特殊的解法
声明一个对象,然后将该数组的元素作为对象的属性名,属性值随便设,然后利用对象属性名不会重复的特点可得到一个对象。接下来再利用Object.keys()拿到属性名。
let test = [1,2,3,1,3,5,2,4,6]
function unique4(arr) {
let newObj = {};
arr.forEach((item) => {
newObj[item] = 0;
});
return Object.keys(newObj).map((item) => +item); //将元素处理成number
}
console.log(unique4(test))
特殊情况:数组中的元素还有引用数据类型:数组、对象,如:[1, 1, 2, 3, [4], [4], 5, 6, 6, { 7: 7 }, { 7: 7 }]
思路:元素转成JSON数据再对比,需要用到JSON.stringify()函数
let test = [1, 1, 2, 3, [4], [4], 5, 6, 6, { 7: 7 }, { 7: 7 }];
function unique(arr) {
let newArr = [];
arr.forEach((item) => {
let isClude = false;
newArr.forEach((item1) => {
if (JSON.stringify(item) === JSON.stringify(item1)) {
isClude = true;
}
});
if (!isClude) {
newArr.push(item);
}
});
return newArr;
}
console.log(unique(test));
进一步优化:和上面基本数据类型去重的方法四一样,借助一个map + 遍历 优化时间复杂度
function unique (arr) {
let newArr = []
let obj = {}
arr.forEach(item => {
if (typeof item !== 'object') {
if (newArr.indexOf(item) === -1) {
newArr.push(item)
}
} else {
let str = JSON.stringify(item)
if (!obj[str]) {
newArr.push(item)
obj[str] = 1
}
}
})
return newArr
}