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去重



参考:
JavaScript专题之数组去重