Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript数组去重的多种方式及优缺点 #9

Open
GGXXMM opened this issue Aug 4, 2019 · 0 comments
Open

JavaScript数组去重的多种方式及优缺点 #9

GGXXMM opened this issue Aug 4, 2019 · 0 comments
Labels
⭐️ js js knowledge

Comments

@GGXXMM
Copy link
Owner

GGXXMM commented Aug 4, 2019

var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];

对这一数组进行去重,有如下方法:

ES6数组去重(4种)

1、使用Set去重

function unique (arr) {
  return [...new Set(arr)];
}
// output:{}没去重
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

优点:方法简洁,实现代码最少
缺点:这种方法无法去掉'{}'空对象

2、利用Map结构

function unique(arr) {
	let map = new Map();
	let array = [];
	for (let i = 0; i < arr.length; i++) {
	        if(map.has(arr[i])) {// 判断map是否有当前key
			map.set(arr[i], true);
		} else {
			map.set(arr[i], false);
			array.push(arr[i]);
		}
	}
	return array;
}
// output:{}没去重
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

优点:利用Map结构,遍历数组,将每个元素作为key存入Map中,去重高效。
缺点:这种方法无法去掉'{}'空对象

3、使用includes去重

function unique(arr) {
	var array = [];
	for (var i = 0; i < arr.length; i++) {
		if(!array.includes(arr[i])){// includes判断该元素是否存在
			array.push(arr[i]);
		}
	}
	return array;
}

// output:{}没去重
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

优点:这种方法去重逻辑简单易懂
缺点:这种方法无法去掉'{}'空对象

4、使用reduce+includes去重

function unique(arr) {
	return arr.reduce((prev, cur) => 
		prev.includes(cur) ? prev : [...prev,cur]
	, [])
}

// output:{}没去重
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

JavaScript原生数组去重(7种)

1、for循环嵌套for循环,使用splice去重(ES5最常用)

function unique(arr) {
	for (var i = 0; i < arr.length; i++) {
		for (var j = i+1; j < arr.length; j++) {
			if(arr[i] == arr[j]){
				arr.splice(j,1);// 删除后一个重复元素
				j--;
			}
		}
	}
	return arr;
}

// output:NaN和{}没有去重,2个true、null直接去掉了
// [1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {}, {}]

优点:正向思维,删除重复的元素,该方法容易理解
缺点:
1)双层循环,时间复杂度为O(n^2),效率较低
2)NaN和{}空对象都没有去重,为true的布尔值、null值会直接被删除

2、利用indexOf去重

function unique(arr) {
    var array = [];
    for (var i = 0; i < arr.length; i++) {
      if (array.indexOf(arr[i]) === -1) {// indexOf判断新数组是否已有当前元素
        array.push(arr[i])
      }
    }
    return array;
}

// output:NaN和{}没有去重
// [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {}, {}]

缺点:NaN和{}空对象都没有去重

3、先sort排序,再比较相邻元素

// sort排序后,再比较相邻元素
function unique(arr) {
	arr = arr.sort();
	var array = [arr[0]];
	for (var i = 1; i < arr.length; i++) {
		if(arr[i] !==  arr[i-1]) {// 如果排序后数组的当前元素!=前一个元素,就push到新数组
			array.push(arr[i]);
		}
	}
	return array;
}

// output:NaN和{}没有去重
// [0, 1, 15, NaN, NaN, "NaN", {…}, {…}, "a", false, null, "true", true, undefined]

缺点:NaN和{}空对象都没有去重

4、使用递归去重

function unique(arr) {
	var array = arr;
	var len = arr.length;

	array.sort();//排序后更加方便去重
	function loop(index) {
		if(index >= 1) {
			if(array[index] === array[index-1]) {
				array.splice(index,1);
			}
			loop(index - 1); // 递归调用loop函数
		}
	}
	loop(len -1);
	return array;
}

// output:NaN和{}没有去重
// [0, 1, 15, NaN, NaN, "NaN", {}, {}, "a", false, null, "true", true, undefined]

缺点:NaN和{}空对象都没有去重

5、使用filter

function unique(arr) {
	return arr.filter(function(item, index, arr) {
		  //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
		  return arr.indexOf(item) === index;
	});
}

// output:{}没有去重,NaN和‘NaN’进行去重了
// [1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {}, {}]

缺点:{}空对象没有去重,对NaN和‘NaN’错误去重

6、利用对象属性不能相同的特点去重(去重有问题,不建议使用)

function unique6(arr) {
	var array = [];
	var obj = {};

	for (var i = 0; i < arr.length; i++) {
		if(!obj[arr[i]]) {// 判断是否有当前属性
			array.push(arr[i]);
			obj[arr[i]] = 1;
		}
	}
	return array;
}

// output:2个true直接去掉了,NaN和‘NaN’进行去重了
// [1, "true", 15, false, undefined, null, NaN, 0, "a", {}]

缺点:2个true直接删除了,对NaN和‘NaN’错误去重

7、使用hasOwnProperty(所有数值都去重)

function unique(arr) {
	var obj = {};
	return arr.filter(function(item, index, arr) {
		return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
	});
}
// output
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}]

优点:这方法能过滤所有数据类型,并完美地去重

@GGXXMM GGXXMM changed the title JavaScript数据去重的多种方式及优缺点 JavaScript数组去重的多种方式及优缺点 Aug 10, 2019
@GGXXMM GGXXMM added the ⭐️ js js knowledge label Dec 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⭐️ js js knowledge
Projects
None yet
Development

No branches or pull requests

1 participant