跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

js数组去重的常用方法总结

JS实现数组去重(重复的元素只保留一个)

1、遍历数组法

1.遍历数组法

它是最简单的数组去重方法(indexOf方法)

实现思路:新建一个数组,遍历去要重的数组,当值不在新数组的时候(indexOf为-1)就加入该新数组中;

例子1function unique(arr) {if (!Array.isArray(arr)) {console.log('type error!') return}var array = [];for (var i = 0; i < arr.length; i++) {if (array .indexOf(arr[i]) === -1) {array .push(arr[i])}}return array;}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr))// [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}] //NaN、{}没有去重例子2var arr=[2,8,5,0,5,2,6,7,2];function unique1(arr){var hash=[];for (var i = 0; i < arr.length; i++) {if(hash.indexOf(arr[i])==-1){hash.push(arr[i]);}}return hash;}

2.数组下标判断法

调用indexOf方法,性能和方法1差不多实现思路:如果当前数组的第 i 项在当前数组中第一次出现的位置不是 i,那么表示第 i 项是重复的,忽略掉。否则存入结果数组。

function unique2(arr){var hash=[];for (var i = 0; i < arr.length; i++) {if(arr.indexOf(arr[i])==i){hash.push(arr[i]);}}return hash;}

3.排序后相邻去除法

实现思路:给传入的数组排序,排序后相同的值会相邻,然后遍历排序后数组时,新数组只加入不与前一值重复的值。

function unique3(arr){arr.sort();var hash=[arr[0]];for (var i = 1; i < arr.length; i++) {if(arr[i]!=hash[hash.length-1]){hash.push(arr[i]);}}return hash;}

4.优化遍历数组法(不推荐)

实现思路:双层循环,外循环表示从0到arr.length,内循环表示从i+1到arr.length将没重复的右边值放入新数组。(检测到有重复值时终止当前循环同时进入外层循环的下一轮判断)

function unique4(arr){var hash=[];for (var i = 0; i < arr.length; i++) {for (var j = i+1; j < arr.length; j++) {if(arr[i]===arr[j]){++i;}}hash.push(arr[i]);}return hash;}上面遍历经过测试后有bug,并不能完全去重

因为这次我做的是对js对象元素去重,我在参考时发现此bug,如果时数组去重,建议用第一种方法。

quan_lst 里面是一个一个的js字面量对象,根据json里面的属性进行判定去重function unique(quan_lst){//去掉重复选取的数据for (var i = 0; i < quan_lst.length; i++) {for (var j =i+1; j

quan_lst.splice(j, 1);//去除重复的对象;

}else {j++;}}}}

5.ES6实现

基本思路:ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。

function unique5(arr){var x = new Set(arr);return [...x];}利用ES6 Set去重(ES6中最常用)

function unique (arr) {return Array.from(new Set(arr))}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr))//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]扩展:如果重复,则去掉该元素数组下标去重function unique22(arr){var hash=[];for (var i = 0; i < arr.length; i++) {if(arr.indexOf(arr[i])==arr.lastIndexOf(arr[i])){hash.push(arr[i]);}}return hash;}补充:原先自己一直以为indexOf是针对字符串,原来indexOf也可以查询出数组元素所在的数组中的位置(以0开始计算),

以上转自于轩悦的博客,学了很多思路。

6、利用sort()

利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对。

function unique(arr) {if (!Array.isArray(arr)) {console.log('type error!') return;}arr = arr.sort() var arrry= [arr[0]];for (var i = 1; i < arr.length; i++) {if (arr[i] !== arr[i-1]) {arrry.push(arr[i]);}}return arrry;}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr))// [0, 1, 15, "NaN", NaN, NaN, {…}, {…}, "a", false, null, true, "true", undefined] //NaN、{}没有去重

7、利用includes

includes 检测数组是否有某个值function unique(arr) {if (!Array.isArray(arr)) {console.log('type error!') return}var array =[];for(var i = 0; i < arr.length; i++) {if( !array.includes( arr[i]) ) {//includes 检测数组是否有某个值array.push(arr[i]);}}return array}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr))//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}] //{}没有去重

八、利用for嵌套for,然后splice去重(ES5中最常用)推荐

双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。

function unique(arr){for(var i=0; i9、利用对象的属性不能相同的特点进行去重(这种数组去重的方法有问题,不建议用,有待改进)

function unique(arr) {if (!Array.isArray(arr)) {console.log('type error!') return}var arrry= [];var obj = {};for (var i = 0; i < arr.length; i++) {if (!obj[arr[i]]) {arrry.push(arr[i]) obj[arr[i]] = 1} else {obj[arr[i]]++}}return arrry;}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr))//[1, "true", 15, false, undefined, null, NaN, 0, "a", {…}] //两个true直接去掉了,NaN和{}去重

十、利用hasOwnProperty

利用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)})}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr))//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}] //所有的都去重了

十一、利用filter

function unique(arr) {return arr.filter(function(item, index, arr) {//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素return arr.indexOf(item, 0) === index;});}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr))//[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]

十二、利用递归去重

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

array.sort(function(a,b){ //排序后更加方便去重return a - b;})

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;}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr))//[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]

十三、利用Map数据结构去重

创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。

function unique(arr){return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr));// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

十四、利用reduce+includes

function unique(arr){return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr));// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

十五、[...new Set(arr)]

[...new Set(arr)]//代码就是这么少----(其实,严格来说并不算是一种,相对于第一种方法来说只是简化了代码)PS:有些文章提到了foreach+indexOf数组去重的方法,个人觉得都是大同小异,所以没有写上去。

下面是其他网友的补充第一种是比较常规的方法

思路:

1.构建一个新的数组存放结果

2.for循环中每次从原数组中取出一个元素,用这个元素循环与结果数组对比

3.若结果数组中没有该元素,则存到结果数组中

Array.prototype.unique1 = function(){var res = [this[0]];for(var i = 1; i < this.length; i++){var repeat = false;for(var j = 0; j < res.length; j++){if(this[i] == res[j]){repeat = true;break;}}if(!repeat){res.push(this[i]);}}return res;}var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]alert(arr.unique1());第二种方法比上面的方法效率要高

思路:

1.先将原数组进行排序

2.检查原数组中的第i个元素 与 结果数组中的最后一个元素是否相同,因为已经排序,所以重复元素会在相邻位置

3.如果不相同,则将该元素存入结果数组中

Array.prototype.unique2 = function(){this.sort(); //先排序var res = [this[0]];for(var i = 1; i < this.length; i++){if(this[i] !== res[res.length - 1]){res.push(this[i]);}}return res;}var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]alert(arr.unique2());第二种方法也会有一定的局限性,因为在去重前进行了排序,所以最后返回的去重结果也是排序后的。如果要求不改变数组的顺序去重,那这种方法便不可取了。

第三种方法(推荐使用)

思路:

1.创建一个新的数组存放结果

2.创建一个空对象

3.for循环时,每次取出一个元素与对象进行对比,如果这个元素不重复,则把它存放到结果数组中,同时把这个元素的内容作为对象的一个属性,并赋值为1,存入到第2步建立的对象中。

说明:至于如何对比,就是每次从原数组中取出一个元素,然后到对象中去访问这个属性,如果能访问到值,则说明重复。

Array.prototype.unique3 = function(){var res = [];var json = {};for(var i = 0; i < this.length; i++){if(!json[this[i]]){res.push(this[i]);json[this[i]] = 1;}}return res;}

var arr = [112,112,34,'你好',112,112,34,'你好','str','str1'];alert(arr.unique3());以上就是js数组去重的三种常用方法总结的详细内容,更多关于js数组去重的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:js数组去重的5种算法实现JS实现数组去重方法总结(六种方法)史上最全JavaScript数组去重的十种方法(推荐)

高性能js数组去重(12种方法,史上最全) JavaScript中数组去重的5种方法js数组去重的11种方法七种JS实现数组去重的方式JavaScript数组去重的15种方法总结

相关文章