2010-02-21 23 views
5

Hola, me preguntaba si alguien podría ofrecer algún consejo sobre la forma más rápida/más eficiente de comprender dos matrices de cadenas en JavaScript.La forma más rápida/más eficiente de comparar dos matrices de cadenas Javascript

Estoy desarrollando un tipo de cosa de tipo nube de etiquetas basada en la entrada de un usuario; la entrada es en forma de un texto escrito, como un artículo de blog o similares.

por lo tanto tengo una matriz que guardo de las palabras para que no incluya - es decir, una, el, etc, etc

En el momento que estoy haciendo lo siguiente:

quita todos los puntuacion de la cadena de entrada , tokenize, compare cada palabra con la matriz de exclusión y luego elimine los duplicados.

Las comparaciones se realizan haciendo un bucle sobre cada elemento en la matriz de exclusión para cada palabra en el texto de entrada; esto parece una especie de fuerza bruta y se cuelga Internet Explorer en arreglos de más de unos cientos de palabras.

También debería mencionar que mi lista de exclusiones tiene alrededor de 300 artículos.

Cualquier ayuda sería realmente apreciada.

Gracias

Respuesta

0

Se podría utilizar una función hash para cadenas (no sé si JS tiene uno pero estoy seguro tío Google puede ayudar;]). Luego, calcularía hash para todas las palabras en su lista de exclusión y crearía una matriz af booleans indexada por esos valores hash. Luego solo itere a través del texto y verifique los hash de palabras en contra de esa matriz.

+0

gracias por la respuesta, sin duda me mirar en eso, pero cuánto más rápido será esto, puesto que está siendo esencialmente la iteración en el mismo número de elementos de las la misma cantidad de veces ¿verdad? – David

+0

No. El algoritmo que presentó tiene complejidad O (n * m * k) donde n es el tamaño de la lista de exclusión, m - tamaño del texto yk es el número promedio de operaciones en la comparación de cadenas. El método que propongo tiene O (n) complejidad para el hashing inicial y O (m) para cada comparación – pablochan

5

No estoy seguro de todo el enfoque, pero en lugar de construir una gran matriz y luego iterar sobre ella, ¿por qué no poner las "claves" en un mapa? ¿Objeto "similar" para una comparación más fácil?

p. Ej.

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

Luego, cuando se desea comparar ... acaba de hacer

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 
    } 
} 

permite que estas palabras a través ['are','my','to','check','for']

+1

+1 Yup, así es como yo lo haría, también ... –

+1

Para evitar cualquier posibilidad de que esto vaya mal debido a Aumento de 'Object.prototype' (por ejemplo, si una biblioteca ha agregado un método' each' a 'Object.prototype'," cada "se considerará una palabra incorrecta en el código de ejemplo), puede usar jshashtable (http: //www.timdown.co.uk/jshashtable/). –

+0

esto tiene sentido. Lo he implementado y ti funciona muy bien en Firefox, pero aún falla, es decir, como lo hizo antes. Me pregunto si es conocido por problemas como este o si mi código puede mejorarse. – David

2

valdría la pena un intento de combinar las palabras en una sola expresión regular, y luego compara con eso. Las optimizaciones del motor de expresiones regulares pueden permitir que la búsqueda salte hacia adelante a través del texto de búsqueda de manera mucho más eficiente de lo que podría hacer iterándose en cadenas separadas.

0

yo he tomado la respuesta de scunliffe y modificado del modo siguiente:

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

Ahora vamos a crear prototipos de una función que comprueba si un valor está dentro de una matriz:

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

permite probar algunas palabras:

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); 
    } 
} 

de salida:

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

me gustaría optar por la versión de expresiones regulares

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 
Cuestiones relacionadas