将Array.indexOf用于相对较大的数组

时间:2014-06-30 12:30:26

标签: javascript

有没有办法实现indexOf功能,找出字符串是否在数组上,对于非常大的数组来说相对较快?当我的数组超过40,000个值时,我的应用程序会冻结几秒钟。

请考虑以下代码:

var arr = [];

function makeWord()
{
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    return text;
}
function populateArr(){
  for (var i=0;i<40000;i++){
    arr[i] = makeWord();
  }
  console.log("finished populateArr");
}
function checkAgainst(){
  for (var i=0;i<40000;i++){
    var wordToSearch = makeWord();
    if (isFound(wordToSearch)){
      console.log("found "+wordToSearch);
    }
  }
  console.log("finished checkAgainst");
}

function isFound(wordToSearch){
  //return $.inArray(wordToSearch,arr) > -1;
  return arr.indexOf(wordToSearch) > -1;
}

populateArr();
checkAgainst();

FIDDLE here

在这段代码中,我用40k随机字符串填充数组arr。在checkAgainst中,我创建了40,000个其他随机字符串,并检查每个字符串是否在arr上找到。这使铬冻结约2秒钟。在Chrome DevTools上打开探查器,我发现isFound在CPU方面显然很昂贵。即使我在checkAgainst中将for循环迭代次数降低到只有4000,它仍会冻结大约一秒左右。

实际上,我有一个chrome扩展和一系列关键字,增长到大约10k字符串。比,我必须使用Array.indexOf来查看该数组中是否有其他200个关键字。这使得我的页面偶尔会冻结一次,从这个例子我怀疑这是原因。想法?

1 个答案:

答案 0 :(得分:2)

尝试使用对象中的键:

var arr = {};

function makeWord() // unchanged
function populateArr(){
  for (var i=0;i<40000;i++){
    arr[makeWord()] = true;
  }
  console.log("finished populateArr");
}
function checkAgainst() // unchanged

function isFound(wordToSearch){
  return arr[wordToSearch];
}

populateArr();
checkAgainst();

如果您需要单词数组,可以使用Object.keys(arr)

或者,将两者结合起来:拥有一个数组一个对象。使用该对象查找单词是否在数组中,或者使用数组来获取单词本身。这将是一个经典的折衷方案,交易内存使用时间。