首页 新闻 会员 周边 捐助

js如何去除数组中重复项??

0
悬赏园豆:10 [已解决问题] 解决于 2014-11-21 12:42

比如有一个数组arr[1,3,2,3,5,4,2,7],我想把元素个数大于1的都去掉,得到的结果是arr[1,5,4,7],而不是arr[1,3,2,5,4,7],请问怎么用js实现,效率越快越好。

js
冷水寒冰的主页 冷水寒冰 | 初学一级 | 园豆:0
提问于:2014-10-30 14:13
< >
分享
最佳答案
0

给你看一种实现:

arr = [1,3,2,3,5,4,2,7]

var m = {}, result = [];
arr.forEach(function(obj, i){
    m['' + obj] = (m['' + obj] || 0) + 1;
});

for(var p in m){
    if(m[p]===1){
        result.push(+p);
    }
}
result;
收获园豆:5
幻天芒 | 高人七级 |园豆:37207 | 2014-10-30 15:03
console.time('t1')

for(var count = 0; count < 1000; count++){
    var arr = [1,3,2,3,5,4,2,7];

    var m = {}, result = [];
    arr.forEach(function(obj, i){
        m['' + obj] = (m['' + obj] || 0) + 1;
    });

    for(var p in m){
        if(m[p]===1){
            result.push(+p);
        }
    }
    
    result;
}


console.timeEnd('t1')

Array.prototype.hasValueCount = function(value){
    var count = 0;
    for(var i = 0, len = this.length; i < len; i ++){
        if(this[i] === value) {
            count++;
        }
    }
    return count;
};

console.time('t2')

for(var count = 0; count < 1000; count++){
    var arr = [1,3,2,3,5,4,2,7];

    var result = [];

    arr.forEach(function(obj, i){
        if(arr.hasValueCount(obj) === 1){
            result.push(obj);
        }
    });

    result;
}

console.timeEnd('t2')

包含小数据的性能测试。

 

幻天芒 | 园豆:37207 (高人七级) | 2014-10-30 15:16

@幻天芒: 好的,多谢,我看看。

冷水寒冰 | 园豆:0 (初学一级) | 2014-10-30 15:57

@幻天芒: 

m[obj] 为什么要写成这样?
m['' + obj]
ayiis | 园豆:356 (菜鸟二级) | 2014-10-31 00:12

@ayiis: 转换为字符串key,如果是整数的话,会被当成索引。

幻天芒 | 园豆:37207 (高人七级) | 2014-10-31 08:37
其他回答(3)
0

往新数组里放

收获园豆:1
吴瑞祥 | 园豆:29449 (高人七级) | 2014-10-30 14:18

关键是在放的时候得判断当前元素是否存在吧?,重复项的第一个以后的元素能判断是否存在,但是第一个重复项放的时候肯定不存在,那不是就放进去了?

支持(0) 反对(0) 冷水寒冰 | 园豆:0 (初学一级) | 2014-10-30 14:22

@冷水寒冰: 做个判断。如果为第一项则放进去。

支持(0) 反对(0) zuike | 园豆:225 (菜鸟二级) | 2014-10-30 14:37

@冷水寒冰: 遍历新数组,不存在的就放进去。

支持(0) 反对(0) 吴瑞祥 | 园豆:29449 (高人七级) | 2014-10-30 14:39

@zuike: 第一项放进去的话我后边怎么去除?

支持(0) 反对(0) 冷水寒冰 | 园豆:0 (初学一级) | 2014-10-30 15:54
0

采用hash形式 在数据量很大的时候 效率就很明显

Test1:

 1  function Test1() {          
 2             var hashArr = {}, tempArr = []; //hashArr为hash表,tempArr为临时数组
 3             var arr = [1, 3, 2, 3, 5, 4, 2, 7];
 4             var d11 = new Date();
 5             var st = d11.getTime();
 6             for (var j = 0; j < 1000000; j++) {
 7                 for (var i = 0,len=arr.length; i < len; i++)
 8                 {
 9                     if (!hashArr[arr[i]])
10                     {
11                         hashArr[arr[i]] = true;
12                         tempArr.push(this[i]);
13                     }
14                 }
15             }
16             var d12 = new Date();
17             var et = d12.getTime();           
18             alert("Test1 Length:" + tempArr.length + "  And Time:" + (et - st) / 1000);
19         }       
View Code

结果如下:

Test2:(幻天芒的方法对比)

 1  function Test2()
 2         {
 3             var arr = [1, 3, 2, 3, 5, 4, 2, 7];
 4             var m = {}, result = [];
 5             var d21 = new Date();
 6             var startTime = d21.getTime();
 7             for (var count = 0; count < 1000000; count++) {
 8                 arr.forEach(function (obj, i) {
 9                     m['' + obj] = (m['' + obj] || 0) + 1;
10                 });
11                 for (var p in m) {
12                     if (m[p] === 1) {
13                         result.push(+p);
14                     }
15                 }
16             }
17             var d22 = new Date();
18             var endTime = d22.getTime();
19             alert("Test2 Length:" + result.length + "  And Time:" + (endTime - startTime) / 1000);
20         }
View Code

结果:

 

由此看出 Test1 比Test2强,结果数量 Test1 要正确些 

收获园豆:2
Chaoa | 园豆:643 (小虾三级) | 2014-10-30 16:40

你没坑我?而且你的结果也不太对。

请看以下的完整测试代码:

var arr = [1, 3, 2, 3, 5, 4, 2, 7];
var testCount = 100000;
Array.prototype.hasValueCount = function(value){
    var count = 0;
    for(var i = 0, len = this.length; i < len; i ++){
        if(this[i] === value) {
            count++;
        }
    }
    return count;
};

//测试一
console.time('t1');
for (var j = 0; j < testCount; j++) {
    var hashArr = {}, tempArr = []; //hashArr为hash表,tempArr为临时数组
  for (var i = 0,len=arr.length; i < len; i++)
  {
    if (!hashArr[arr[i]])
    {
      hashArr[arr[i]] = true;
      tempArr.push(this[i]);
    }
  }
}
console.timeEnd('t1');

//测试二
console.time('t2');
var m = {}, result = [];
for (var count = 0; count < testCount; count++) {
  arr.forEach(function (obj, i) {
    m['' + obj] = (m['' + obj] || 0) + 1;
  });
  for (var p in m) {
    if (m[p] === 1) {
      result.push(+p);
    }
  }
}
console.timeEnd('t2')

//测试三
console.time('t3')
for(var count = 0; count < testCount; count++){
    var result = [];
    arr.forEach(function(obj, i){
        if(arr.hasValueCount(obj) === 1){
            result.push(obj);
        }
    });
}
console.timeEnd('t3')

从结果来看,当testCount=1000(较小)时,方案三是三者中最快的。当testCount = 1000000(较大)时,方案二是三者中最快的。

以上代码可直接复制到Chrome控制台执行。

支持(0) 反对(0) 幻天芒 | 园豆:37207 (高人七级) | 2014-10-31 09:00
0

倒序遍历,删除大于1的元素。

1 var arr=[1,3,2,3,5,4,2,7];
2 for(var i=arr.length-1,i>=0;i--)
3 {
4   if(arr[i]>1)
5   {
6     arr.remove(i);
7   }
8 }
收获园豆:2
xiaoafei1991 | 园豆:466 (菜鸟二级) | 2014-11-02 13:02
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册