Оптимизировать код javascript при поиске совпадений в массиве
В принципе, мне нужно получить слова из массива, которые содержатся в основной строке
У меня есть код цикла, но я думаю, что есть один-лайнер, чтобы сделать трюк.
Мне нужен код для оптимизации не только длины кода, но и производительности.
Спасибо
var aValidWords = ["ex", "exes", "expert",
"experts", "expertise", "sex", "sexes",
"exchange", "change", "changes"];
var sMainWord = "expertsExchange";
var aPossibleWords = new Array();
var sMainWordLower = sMainWord.toLowerCase();
for(i=0; i < aValidWords.length; i++){
var sCurrentWord = aValidWords[i].toLowerCase();
if(sMainWordLower.indexOf(sCurrentWord) != -1){
aPossibleWords.push(aValidWords[i]);
}
}
document.write(aPossibleWords.join("<br />"));
Ответы
Ответ 1
Я думаю, что ваш код приличный.
Если вас действительно беспокоит производительность, вы можете попробовать какой-то сложный метод, например Boyer-Moore.
Но если у вас просто несколько паттернов и относительно короткие строки, тогда накладные расходы на инициализацию выше, чем преимущество, поэтому вы должны придерживаться простого подхода. См. Таблицу сравнения Википедии http://en.wikipedia.org/wiki/String_searching_algorithm#Single_pattern_algorithms
Ответ 2
Я сравнил три возможные реализации:
Альтернатива 1 - Использование для цикла:
function alternative1(aValidWords, sMainWordLower) {
var aPossibleWords1 = [];
for(i=0; i < aValidWords.length; i++){
if(sMainWordLower.indexOf(aValidWords[i]) != -1){
aPossibleWords1.push(aValidWords[i]);
}
}
return aPossibleWords1;
}
Альтернатива 2 - Использование функции jQuery grep:
function alternative2(aValidWords, sMainWordLower) {
return $.grep(aValidWords, function(word) {
return sMainWordLower.indexOf(word) != -1;
}
)
}
Альтернатива 3. Использование JavaScript native фильтр (IE9, Chrome, Firefox, Opera, Safari):
function alternative3(aValidWords, sMainWordLower) {
return aValidWords.filter(function(word) {
return sMainWordLower.indexOf(word) != -1;
}
)
}
Я измерил время выполнения с помощью инструмента профиля Chrome. Каждая альтернатива была выполнена 10 раз с массивом случайных слов milion. Результаты:
- Альтернатива 1: 20 исполнений → 21,68s
- Альтернатива 2: 20 исполнений → 26,31s
- Альтернатива 3: 20 исполнений → 34,66s
Я был удивлен тем фактом, что эта функция JavaScript Filter была настолько медленной.
Если вы не будете самостоятельно измерять время выполнения, jsFiddle - это займет некоторое время для script закончить.
В целом эти три альтернативы проще всего. Если это время выполнения подходит вам, используйте один из них, иначе ответ @Pumbaa80 будет правильным.
[ОБНОВЛЕНИЕ]
Для объяснения результатов (почему функция JQuery grep быстрее, чем функция встроенного JavaScript-фильтра), обратите внимание на этот вопрос .
jsFiddle код также был перенесен на jsPerf благодаря @Alexander.
Ответ 3
Этот цикл определенно более краток, чем тот, который у вас есть, но стоит попробовать несколько тестов в разных браузерах, чтобы узнать, что быстрее. Я предполагаю, что соответствие Regex возможно быстрее, но мне любопытно, есть ли какое-либо ограничение производительности для компиляции Regex.
for(var i=0; i<aValidWords.length; i++) {
if (new RegExp(aValidWords[i], 'i').test(sMainWord))
aPossibleWords.push(aValidWords[i]);
}