数组中某个元素相同的去重_js数组去重的常用方法总结

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

1、遍历数组法

1.遍历数组法

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

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

例子1

function 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、{}没有去重

例子2

var 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

if (quan_lst[i].photoid == quan_lst[j].photoid ) {//通过photoid属性进行匹配;

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; i

for(var j=i+1; j

if(arr[i]==arr[j]){ //第一个等同于第二个,splice方法删除第二个

arr.splice(j,1);

j--;

}

}

}

return 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", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}] //NaN和{}没有去重,两个null直接消失了

9、利用对象的属性不能相同的特点进行去重(这种数组去重的方法有问题,不建议用,有待改进)

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数组去重的资料请关注脚本之家其它相关文章!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值