无论是在面试还是项目开发中,阵列重复数据删除都是一个常见的问题。今天老k总结几个有用的阵列重复数据删除方法。ES5的方法:首先使用两次for循环,然后拼接权重(ES5中最常用)f
无论是在面试还是项目开发中,阵列重复数据删除都是一个常见的问题。今天老k总结几个有用的阵列重复数据删除方法。
ES5的方法:
首先使用两次for循环,然后拼接权重(ES5中最常用)
function unique(arr){ if(toString.call(arr) !== "[object Array]"){ console.log('必须为数组'); return ; } for(var i=0; i<arr.length; i++){ for(var j = i+1; j<arr.length; j++){ if(arr[i] === arr[j]){ //第一个等同于第二个,splice方法删除第二个 arr.splice(j,1); j--; } } } return arr;};var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}];unique(arr); // [2, "a", true, "true", false, "false", undefined, null, NaN, NaN, "NaN", 0, {…}, {…}]
原理:双循环,外循环元素,内循环比较值。当值相同时,删除该值。
优点:兼容性强。
缺点:不能复制NaN,object对象。数据量大的时候效率不高。
其次,使用array的排序方法删除重复项
function unique(arr){ if (toString.call(arr) !== "[object Array]"){ console.log('必须为数组'); return; } arr = arr.sort() var new_array = [arr[0]]; for(var i =1; i<arr.length; i++){ if(arr[i] !== arr[i-1]){ new_array.push(arr[i]); } } return new_array;};var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}];unique(arr);//[0, 2, NaN, NaN, "NaN", {…}, {…}, "a", false, "false", null, true, "true", undefined]
原理:使用sort()排序方法,然后根据排序结果遍历比较相邻元素。
优点:兼容性强,逻辑简单,容易理解。
缺点:不能复制NaN,object对象。
第三,利用对象的属性不能相同的特性进行重复数据删除,主要使用hasOwnProperty
function unique(arr){ if (toString.call(arr) !== "[object Array]"){ console.log('必须为数组'); return; } var obj = {}; var new_arr = []; for(var i = 0; i< arr.length; i++){ if(!obj.hasOwnProperty(typeof arr[i]+arr[i])){ new_arr.push(arr[i]); obj[typeof arr[i]+arr[i]] = true; } } return new_arr}var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}];unique(arr); //[2, "a", true, "true", false, "false", undefined, null, NaN, "NaN", 0, {…}]
原理:新建空对象,空数组,遍历目标数组。如果元素不是对象的键,则将元素添加到新数组中,并为键赋值。如果它已经是对象的键,则忽略它。区分布尔值和”按true类型的布尔值”、“假”,南和“南”。
优势:可以对各种类型的数据进行重复数据删除。
缺点:还没有。
ES6的方法:
1。使用ES6的Set对象的特征进行重复数据删除
function unique(arr){ if(!Array.isArray(arr)){ console.log('必须为数组'); return; } return Array.from(new Set(arr)) //或者用扩展运算符转化为数组 return [...new Set(arr)]};var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}];unique(arr); // [2, "a", true, "true", false, "false", undefined, null, NaN, "NaN", 0, {...},{...}]
原理:利用ES6的Set对象自动消除重复项的特性,Set对象通过from方法或ES6数组的扩展操作符转换成数组。
优点:不考虑兼容性,这个方法代码最少。
缺点:这种方法不能复制object对象,所以要考虑兼容性问题。
其次,使用重复数据删除的ES6索引的阵列方法
function unique(arr){ if(!Array.isArray(arr)){ console.log('必须为数组'); return; } var new_array = []; for(var i = 0; i< arr.length; i++){ if (new_array.indexOf(arr[i]) === -1){ new_array.push(arr[i]) } } return new_array;};var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}];unique(arr); //[2, "a", true, "true", false, "false", undefined, null, NaN, NaN, "NaN", 0, {…}, {…}]
原理:创建空的新结果数组,循环原来的数组为。使用indexOf方法确定结果数组中是否有当前元素。如果有相同的值,跳过它们,如果它们不同,就将它们推入数组。
优点:使用ES6阵列的新方法逻辑简单,易于理解。
缺点:不能复制NaN,object对象,需要考虑兼容性问题。
三。使用ES6阵列方法包括重复数据消除
function unique(arr){ if(!Array.isArray(arr)){ console.log('必须为数组'); return; } var new_array = []; for(var i = 0; i< arr.length; i++){ if ( !new_array.includes(arr[i]) ){ new_array.push(arr[i]) } } return new_array;};var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}];unique(arr); //[2, "a", true, "true", false, "false", undefined, null, NaN, "NaN", 0, {…}, {…}]
原理:创建一个新的空数组new_array,遍历目标数组,用includes方法判断目标数组的元素是否在新数组中。如果没有,则将元素添加到新数组中,如果有,则忽略它们。
优点:使用ES6阵列的新方法逻辑简单,易于理解。
缺点:不能复制object对象,需要考虑兼容性。
四。使用ES6筛选器和indexOf进行重复数据消除
function unique(arr){ if(!Array.isArray(arr)){ console.log('必须为数组'); return; } return arr.filter(function(item, index, arr){ return arr.indexOf(item, 0) === index; });}var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}];unique(arr); //[2, "a", true, "true", false, "false", undefined, null, "NaN", 0, {…}, {…}]
原理:给filter一个过滤条件,获取原数组中某个元素的第一个索引,如果等于当前索引值,则返回当前元素。
优点:使用ES6阵列的新方法逻辑简单,易于理解。
缺点:不能复制object和NaN,需要考虑兼容性。
五、使用ES6的地图数据格式进行重复数据删除
function unique(arr){ if(!Array.isArray(arr)){ console.log('必须为数组'); return; } let map = new Map(); let new_array = new Array(); for(let i = 0; i<arr.length; i++){ if(map.has(arr[i])){ map.set(arr[i], true); }else{ map.set(arr[i], false); new_array.push(arr[i]); } } return new_array;}var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}];unique(arr); //[2, "a", true, "true", false, "false", undefined, null, NaN, "NaN", 0, {…}, {…}]
原理:创建一个新数组,遍历目标数组,如果元素不在Map中,就向新数组中添加元素。
优点:采用ES6阵列的全新数据结构,逻辑简单易懂。
缺点:不能复制object对象,需要考虑兼容性。
六。使用ES6的reduce和includes进行重复数据消除
function unique(arr){ if(!Array.isArray(arr)){ console.log('必须为数组'); return; } return arr.reduce( (prev, cur) => prev.includes(cur) ? prev : [...prev,cur], []);}var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}];unique(arr); //[2, "a", true, "true", false, "false", undefined, null, NaN, "NaN", 0, {…}, {…}]
原理:创建一个新数组,遍历目标数组,如果元素不在Map中,就向新数组中添加元素。
优点:利用ES6数组的reduce,将初始值设置为一个空数组,迭代判断当前元素是否在前一个数组中,如果是,则返回前一个数组,否则,将当前元素加到前一个元素中,然后返回新的数组。
缺点:不能复制object对象,需要考虑兼容性。