2010-02-21 6 views
5

Привет, мне было интересно, может ли кто-нибудь предложить совет по самому быстрому/наиболее эффективному способу составить два массива строк в javascript.Самый быстрый/самый эффективный способ сравнения двух массивов строк Javascript

Я разрабатываю вид типа облачного типа тегов, основанный на вводе пользователей - вход в форме написанного фрагмента текста, например, статьи в блоге или подобных.

поэтому у меня есть массив, который я храню слов, чтобы не включать - это, а, и т.д. и т.п.

На данный момент я делаю следующее:

Удалить все знаки препинания из строки ввода , tokenize, сравнить каждое слово с массивом exclude и затем удалить любые дубликаты.

Сравнение выполняется с помощью циклического перебора каждого элемента в массиве exclude для каждого слова во входном тексте - это похоже на грубую силу и сбой Internet Explorer на массивах более чем на несколько сотен слов.

Я также должен упомянуть, что мой список исключений насчитывает около 300 наименований.

Любая помощь будет действительно оценена.

Благодаря

ответ

0

Вы можете использовать хэш-функцию для строк (я не знаю, если JS имеет один, но я уверен, что дядя Google может помочь;]). Затем вы вычисляете хэши для всех слов в вашем списке исключений и создаете массив af booleans, индексированный этими хэшами. Затем просто перебираем текст и проверяем хэши слова на этот массив.

+0

спасибо за ответ, я, безусловно, смотреть на это, но, насколько быстрее это может быть, так как вы по-прежнему в основном итерации тем же число элементов такое же количество раз не вы? – David

+0

Нет. Алгоритм, который вы представили, имеет сложность O (n * m * k), где n - размер списка исключений, размер m-текста и k - среднее число операций в сравнении строк. Предлагаемый метод имеет сложность O (n) для начального хэширования и O (m) для каждого сравнения – pablochan

5

Я не уверен в целом, но вместо того, чтобы строить массив, а затем перебирать его, почему бы не поместить «ключи» в объект «как» для упрощения сравнения?

например.

var excludes = {};//object 
//set keys into the "map" 
excludes['bad'] = true; 
excludes['words'] = true; 
excludes['exclude'] = true; 
excludes['all'] = true; 
excludes['these'] = true; 

Затем, когда вы хотите сравнить ... вобще

var wordsToTest = ['these','are','all','my','words','to','check','for']; 
var checkWord; 
for(var i=0;i<wordsToTest.length;i++){ 
    checkWord = wordsToTest[i]; 
    if(excludes[checkword]){ 
    //bad word, ignore... 
    } else { 
    //good word... do something with it 
    } 
} 

позволяет эти слова через ['are','my','to','check','for']

+1

+1 Yup, вот как я это сделаю ... – 2010-02-21 22:39:50

+1

Чтобы избежать каких-либо шансов на это, добавление «Object.prototype» (например, если библиотека добавила метод 'each' к' Object.prototype', «каждый» будет считаться плохим словом в примере кода), вы можете использовать jshashtable (http: //www.timdown.co.uk/jshashtable/). –

+0

это имеет смысл. Я реализовал его, и ti отлично работает в firefox, но он все равно сбой, т. Е. Как раньше. Интересно, знает ли то, что известно о таких проблемах, или мой код может быть улучшен. – David

2

Это стоило бы попытаться объединить эти слова в одно регулярное выражение, и затем сравните с этим. Оптимизация двигателя регулярного выражения может позволить поиску пропустить вперед текст поиска намного эффективнее, чем вы могли бы сделать, итерации себя по отдельным строкам.

0

Я принял ответ scunliffe и изменил его следующим образом:

var excludes = ['bad','words','exclude','all','these']; //array 

теперь позволяет прототипу функцию, которая проверяет, является ли значение внутри массива:

Array.prototype.hasValue= function(value) { 
    for (var i=0; i<this.length; i++) 
     if (this[i] === value) return true; 
    return false; 
} 

позволяет проверить некоторые слова:

var wordsToTest = ['these','are','all','my','words','to','check','for']; 
var checkWord; 
for(var i=0; i< wordsToTest.length; i++){ 
    checkWord = wordsToTest[i]; 
    if(excludes.hasValue(checkWord)){ 
    //is bad word 
    } else { 
    //is good word 
    console.log(checkWord); 
    } 
} 

выход:

['are','my','to','check','for'] 
0

Я выбрал бы для версии регулярных выражений

text = 'This is a text that contains the words to delete. It has some <b>HTML</b> code in it, and punctuation!'; 
deleteWords = ['is', 'a', 'that', 'the', 'to', 'this', 'it', 'in', 'and', 'has']; 

// clear punctuation and HTML code 
onlyWordsReg = /\<[^>]*\>|\W/g; 
onlyWordsText = text.replace(onlyWordsReg, ' '); 

reg = new RegExp('\\b' + deleteWords.join('\\b|\\b') + '\\b', 'ig'); 
cleanText = onlyWordsText .replace(reg, ''); 

// tokenize after this 
Смежные вопросы