JavaScript数组去重
双重循环
function unique(arr) {
var newArr = [];
for (var i = 0, len = arr.length; i < len; i++) {
for (var j = i + 1; j < len; j++) {
if (arr[i] === arr[j]) {
j = ++i; //注意不能i++
}
}
newArr.push(arr[i]);
}
return newArr;
}
注意,前面这个方法也不能对NaN和对象进行去重,时间复杂度O(n^2)
通过indexOf直接遍历
function unique(arr) {
var newArr = [];
for (var i = 0, len = arr.length; i < len; i++) {
item = arr[i];
if(newArr.indexOf(item) === -1) {
newArr.push(item);
}
}
return newArr;
}
//前面这种方法不能对对象和NaN进行去重
// 或者判断索引
function unique(arr) {
var newArr = [arr[0]];
var item;
for(var i = 1, len = arr.length; i < len; i++) {
item = arr[i];
if (arr.indexOf(item) === i) {
newArr.push(item);
}
}
return newArr;
}
//前面这种方法不能对对象和NaN进行去重
// 或者用forEach
function unique(arr) {
var newArr = [];
arr.forEach(function(item) {
if(newArr.indexOf(item) === -1) {
newArr.push(item);
}
});
return newArr;
}
//前面这种方法不能对对象和NaN进行去重
// 或者用reduce
function unique(arr) {
return arr.reduce(function(prev, next) {
if(prev.indexOf(next) === -1) {
if(prev.indexOf(next) === -1) {
prev.push(next);
}
return prev;
}, []);
}
//前面这种方法不能对对象和NaN进行去重
// 或者使用filter
function unique(array) {
var res = array.filter(function(item, index, array){
return array.indexOf(item) === index;
})
return res;
}
// 加上排序的功能
function unique(array) {
return array.concat().sort().filter(function(item, index, array){
return !index || item !== array[index - 1];
});
}
//前面这两种方法不能对对象和NaN进行去重,并且加上排序功能的那个方法也不能对相同的类似数字的字符串(比如"2",但是可以处理英文字符串)进行去重
使用indexOf直接遍历数组去重有一个问题,它不能处理NaN去重
排序去邻
首先先对数组内的元素进行排序,接着判断某个索引的元素是否和前一个索引的元素相等即可
function unique(arr){
var newArr = [arr[0]];
var item;
arr.sort();
for(var i = 1, len = arr.length; i < len; i++){
item = arr[i];
if(item !== arr[i - 1]){
newArr.push(item);
}
}
return newArr;
}
注意,前面这个方法也不能对NaN和对象去重
使用Set或Map
ES6引入了Set的数据结构,可以很方便地提供数组去重:
function unique(array) {
return Array.from(new Set(array));
}
// 简化
const unique = (arr) => [...new Set(arr)]
// 使用Map
const unique = (arr) => {
const seen = new Map();
return arr.filter((a) => !seen.has(a) && seen.set(a, 1))
}
Set的数据结构可以很方便地实现数组去重,并且可以避免前面遇到的NaN去重问题, 但是它依旧不能对对象进行去重
最优
function unique(array) {
var obj = {};
return array.filter(function(item, index, array){
console.log(typeof item + JSON.stringify(item))
return obj.hasOwnProperty(typeof item + JSON.stringify(item)) ? false : (obj[typeof item + JSON.stringify(item)] = true)
})
}
这个方法可以处理对象和NaN去重