2011-08-27 62 views
6

我正在为名称构建自动建议。当用户输入文本框时,它会打到服务器并运行:如何更快地匹配此文本?

var names = [ list of 1000 names ]; //I have a list of 1000 names, this is static. 
var query = 'alex'; 
var matched_names = []; 

//This is when it gets slow.... 
names.forEach(function(name){ 
    if(name.indexOf(query) >= 0){ 
     matched_names.push(name); 
    } 
}); 

return matched_names; 

我该如何让这个更快?我正在使用Node.js

+0

请注意,您的代码大小写敏感:'亚历克斯'不会匹配'亚历克斯';这可能是你想要的,但。 – magma

回答

7

如果名称是静态的,那么将此代码移动到客户端并在那里运行。在服务器上运行代码的唯一原因是数据源在某种程度上是动态的。

做这个逻辑客户端将大大提高性能。

1

你应该使用filter而是一两件事,因为它是原生:

var names = [ /* list of 1000 names */ ]; 
var query = 'alex'; 
var matched_names = names.filter(function(name) { 
    return name.indexOf(query) > -1; 
}); 
return matched_names; 
1

如果您存储在有序的名字,那么你可以使用二进制搜索中的排序查找姓名的区域以用户输入的名称片段开始的顺序,而不是逐个检查所有名称。

在一个编程语言相当奇怪的系统上,我希望找到包含用户在任何位置输入的内容的所有匹配项,通过恢复http://en.wikipedia.org/wiki/Key_Word_in_Context,我得到了一个令人满意的结果,没有太多的实施工作。 (一旦在大学我通过物理KWIC索引中,从IBM行式打印机打印出来,然后绑定为眼前这个目的的文件。

1

我会建议你做的客户端这些东西,更喜欢(现在)while循环,而不是一个过滤器/的forEach方法:

var names = [ /* list of 1000 names */ ] 
, query = 'alex' 
, i = names.length 
, matched_names = []; 

while(i--){ 
    if(names[i].indexOf(query) > -1){ 
    matched_names.push(names[i]); 
    } 
} 

return matched_names; 

这会快很多(即使过滤器/的forEach的原生支持)看到这个基准:http://jsperf.com/function-loops/4