JavaScript - 删除重复算法效率

时间:2014-09-29 09:55:01

标签: javascript algorithm duplicate-removal

我已经阅读了很多关于这个主题的内容,我看到了许多不同的算法。我偶然发现了另一种解决方案,与其他算法相比,我很难理解它的效率,因为它使用一个简单的临时对象来保存数组的现有元素。与“旧学校”相比,这是一个有效的解决方案吗?方法使用复杂的排序方法和比较?

 function removeDup(arr){
        var element,
                existObj= {},
                finalArr = [];

        for(var i=0;i<arr.length;i++){
            element = arr[i];
            if(!existObj[element]){
                finalArr.push(element);
                existObj[element] = true;
            }
        }
        return finalArr;
    }
    //console.log(removeDup([2,2,2,2,4534,5,7,3]));
    console.log(removeDup(["mike","john","alex","mike","john"]));

一位朋友告诉我,这里的效率无法明确确定,因为我真的不知道临时对象是如何实现的。

2 个答案:

答案 0 :(得分:1)

通过使用最合适的数据结构,您将获得最佳性能。在像js这样的JIT /解释语言中,使用本机功能的好处是巨大的。

这是一个你应该首先使用的套装:这样你甚至不需要做任何删除重复的事情,添加它们时就会被忽略。
我只做了一个简单的测试,使用Set,性能大约快6到10倍(!!)。

http://jsbin.com/jofofeyixaco/1/edit?js,console

结果示例:

"overhead is : 0.015700000221841037"
"Built unic numbers with a lookup object in : 6.237600000167731"
"Built unic numbers with a Set in : 0.7921500000520609"

以下是两种算法的n = 0到50.000的曲线 我们看到确实哈希映射的行为与O(1)非常相似,但是当n加注时,散布值会更高 Set几乎是线性的。

enter image description here

画jsbin(耐心等待!):http://jsbin.com/jofofeyixaco/2/

代码:

// noprotect
// build a test set
var numbers = [];
var cnt = 10000; 
for (var i=0; i<cnt; i++ ) numbers.push(Math.floor(Math.random*1000));

// build unic values using lookup object
function buildWithObject() {
  var existing= {};
  var unicNumbers = [];
  for (var i=0; i<cnt; i++) {
    var num = numbers[i];
    if (!existing[num]) {
      unicNumbers.push(num);
      existing[num]=true;
    }
  }
}

// build unic values using a Set
function buildWithSet() {
    var unicNumbersSet = new Set();
    for (var i=0; i<cnt; i++) {
         var num = numbers[i];
         unicNumbersSet.add(num);
    }  
}

function iterate() {
    for (var i=0; i<cnt; i++) {
         var num = numbers[i];
    }    
}

// warming up functions
for (var i=0; i<30; i++) { buildWithObject(); buildWithSet() ;  iterate(); }

// --------  Measures  --------------------
var measureRepeat = 20;
var m;

var s,e;
// ----------------------------
m=measureRepeat;
s=window.performance.now();
while (m--) iterate();
e=window.performance.now();

console.log('overhead is : ' + (e-s)/measureRepeat);

// ----------------------------
m=measureRepeat;
s=window.performance.now();
while (m--) buildWithObject();
e=window.performance.now();

console.log('Built unic numbers with a lookup object in : ' + (e-s)/measureRepeat);

// ----------------------------
m=measureRepeat;
s=window.performance.now();
while (m--) buildWithSet();
e=window.performance.now();
console.log('Built unic numbers with a Set in : ' + (e-s)/measureRepeat);

(别忘了,Set是EcmaScript 6,所以在js标签中使用type =“application / javascript; version = 1.7”

如果您担心兼容性:http://kangax.github.io/compat-table/es6/#Set
所有'现代'平台都可以:Ch,FF,IE11,OS8
所有其他人都不行。 )

答案 1 :(得分:0)

let existing = {};
let unicNumbers = [];   
arr.forEach((item) => {
        if (!existing[item.id]) {
            unicNumbers.push(item);
            existing[item.id] = true;
        }
    })