通过大型js字符串数组优化搜索?

时间:2010-10-20 08:10:38

标签: javascript arrays string search

如果我有一个超过10,000个元素的大型javascript字符串数组, 我如何快速搜索它?

现在我有一个javascript字符串数组,用于存储作业的描述, 并且我允许用户在输入框中输入时动态过滤返回的列表。

所以说我有一个像这样的字符串数组:
var descArr = {"flipping burgers", "pumping gas", "delivering mail"};

并且用户想要搜索:"p"

如何快速搜索其中包含10000多条描述的字符串数组? 显然我不能对描述数组进行排序,因为它们是描述,因此二进制搜索已经完成。由于用户可以按"p""pi"或任意字母组合进行搜索,因此此部分搜索意味着我无法使用关联数组(即searchDescArray["pumping gas"]) 加快搜索速度。

任何想法?

5 个答案:

答案 0 :(得分:20)

由于实际浏览器中的正则表达式引擎在速度方面变得疯狂,那么这样做怎么样?而不是数组传递一个巨大的字符串,并用一个标识符分隔单词。 例如:

  • 字符串"flipping burgers""pumping gas""delivering mail"
  • 正则表达式:"([^"]*ping[^"]*)"

使用全局开关/g,您可以获得所有匹配项。确保用户不搜索字符串分隔符。

你甚至可以在字符串中添加一个id:

  • 字符串"11 flipping burgers""12 pumping gas""13 delivering mail"
  • 正则表达式:"(\d+) ([^"]*ping[^"]*)"

  • 示例:http://jsfiddle.net/RnabN/4/(30000个字符串,将结果限制为100)

答案 1 :(得分:4)

如果不做一些更改,就无法加速初始数组查找。您可以通过缓存结果并将它们动态映射到模式来加速连续查找。

1。)调整数据格式。这使初始查找更快一些。基本上,你预先安排。

var data = {
    a : ['Ant farm', 'Ant massage parlor'],
    b : ['Bat farm', 'Bat massage parlor']
    // etc
}

2.)设置缓存机制。

var searchFor = function(str, list, caseSensitive, reduce){
    str = str.replace(/(?:^\s*|\s*$)/g, ''); // trim whitespace
    var found = [];
    var reg = new RegExp('^\\s?'+str, 'g' + caseSensitive ? '':'i');
    var i = list.length;
    while(i--){
        if(reg.test(list[i])) found.push(list[i]);
        reduce && list.splice(i, 1);
    }
}

var lookUp = function(str, caseSensitive){
    str = str.replace(/(?:^\s*|\s*$)/g, ''); // trim whitespace
    if(data[str]) return cache[str];
    var firstChar = caseSensitive ? str[0] : str[0].toLowerCase();
    var list = data[firstChar];
    if(!list) return (data[str] = []);
    // we cache on data since it's already a caching object.
    return (data[str] = searchFor(str, list, caseSensitive)); 
}

3.)使用以下脚本创建一个预先缓存对象。我建议你运行一次并使用JSON.stringify来创建一个静态缓存对象。 (或在后端执行此操作)

// we need lookUp function from above, this might take a while
var preCache = function(arr){
    var chars = "abcdefghijklmnopqrstuvwxyz".split('');
    var cache = {};
    var i = chars.length;
    while(i--){
        // reduce is true, so we're destroying the original list here.
        cache[chars[i]] = searchFor(chars[i], arr, false, true);
    }
    return cache;
}

可能比您预期的更多代码,但优化和性能不是免费的。

答案 2 :(得分:1)

这对你来说可能不是一个答案,因为我对你的设置做了一些假设,但是如果你有服务器端代码和一个数据库,那么你最好再做一个AJAX回调以获得削减下来的结果列表,并使用数据库进行过滤(因为他们非常擅长这种事情)。

除了数据库的好处之外,您还可以从不向基于Web的前端输出这么多数据(10000个变量)中受益 - 如果您只返回所需的数据,那么您将节省相当多的带宽

答案 3 :(得分:1)

我无法重现这个问题,我创建了一个天真的实现,并且大多数浏览器在一个数字毫秒内搜索10000个15个字符串。我不能在IE6中测试,但我不相信它比最快的浏览器慢100多倍,这几乎是即时的。

亲自尝试:http://ebusiness.hopto.org/test/stacktest8.htm(请注意,创建时间与问题无关,只是为了获取一些数据。)

你可能做错的一件事是尝试渲染所有结果,当用户只输入一个字母或一个普通的字母组合时,这将是一项相当大的工作。

答案 4 :(得分:0)

我建议尝试一个现成的JS函数,例如来自jQuery的autocomplete。它很快,并且有很多选项可供配置。

查看jQuery autocomplete demo