如果我有一个超过10,000个元素的大型javascript字符串数组, 我如何快速搜索它?
现在我有一个javascript字符串数组,用于存储作业的描述, 并且我允许用户在输入框中输入时动态过滤返回的列表。
所以说我有一个像这样的字符串数组:
var descArr = {"flipping burgers", "pumping gas", "delivering mail"};
并且用户想要搜索:"p"
如何快速搜索其中包含10000多条描述的字符串数组?
显然我不能对描述数组进行排序,因为它们是描述,因此二进制搜索已经完成。由于用户可以按"p"
或"pi"
或任意字母组合进行搜索,因此此部分搜索意味着我无法使用关联数组(即searchDescArray["pumping gas"]
)
加快搜索速度。
任何想法?
答案 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
。它很快,并且有很多选项可供配置。