Pregunta

¿Cuál es la mejor y más eficiente manera de contar palabras clave en JavaScript? Básicamente, me gustaría tomar una cadena y obtener las mejores N palabras o frases que aparecen en la cadena, principalmente para el uso de etiquetas sugerentes. Busco más sugerencias conceptuales o enlaces a ejemplos de la vida real que el código real, pero ciertamente no me importaría si también quisiera compartir el código. Si hay funciones particulares que ayuden, también lo apreciaría.

Ahora mismo, creo que estoy usando la función split () para separar la cadena por espacios y luego limpiar la puntuación con una expresión regular. También quisiera que no distinga mayúsculas de minúsculas.

¿Fue útil?

Solución

Cortar, pegar + ejecutar demo:

var text = "Text to be examined to determine which n words are used the most";

// Find 'em!
var wordRegExp = /\w+(?:'\w{1,2})?/g;
var words = {};
var matches;
while ((matches = wordRegExp.exec(text)) != null)
{
    var word = matches[0].toLowerCase();
    if (typeof words[word] == "undefined")
    {
        words[word] = 1;
    }
    else
    {
        words[word]++;
    }
}

// Sort 'em!
var wordList = [];
for (var word in words)
{
    if (words.hasOwnProperty(word))
    {
        wordList.push([word, words[word]]);
    }
}
wordList.sort(function(a, b) { return b[1] - a[1]; });

// Come back any time, straaanger!
var n = 10;
var message = ["The top " + n + " words are:"];
for (var i = 0; i < n; i++)
{
    message.push(wordList[i][0] + " - " + wordList[i][1] + " occurance" +
                 (wordList[i][1] == 1 ? "" : "s"));
}
alert(message.join("\n"));

Función reutilizable:

function getTopNWords(text, n)
{
    var wordRegExp = /\w+(?:'\w{1,2})?/g;
    var words = {};
    var matches;
    while ((matches = wordRegExp.exec(text)) != null)
    {
        var word = matches[0].toLowerCase();
        if (typeof words[word] == "undefined")
        {
            words[word] = 1;
        }
        else
        {
            words[word]++;
        }
    }

    var wordList = [];
    for (var word in words)
    {
        if (words.hasOwnProperty(word))
        {
            wordList.push([word, words[word]]);
        }
    }
    wordList.sort(function(a, b) { return b[1] - a[1]; });

    var topWords = [];
    for (var i = 0; i < n; i++)
    {
        topWords.push(wordList[i][0]);
    }
    return topWords;
}

Otros consejos

Una vez que hayas limpiado el conjunto de palabras y digamos que lo llamas wordArray :

var keywordRegistry = {};

for(var i = 0; i < wordArray.length; i++) {
   if(keywordRegistry.hasOwnProperty(wordArray[i]) == false) {
      keywordRegistry[wordArray[i]] = 0;
   }
   keywordRegistry[wordArray[i]] = keywordRegistry[wordArray[i]] + 1;
}

// now keywordRegistry will have, as properties, all of the 
// words in your word array with their respective counts 

// this will alert (choose something better than alert) all words and their counts
for(var keyword in keywordRegistry) {
  alert("The keyword '" + keyword + "' occurred " + keywordRegistry[keyword] + " times");
}

Eso debería darle los conceptos básicos para hacer esta parte del trabajo.

Intenta dividir tu cadena en palabras y cuenta las palabras resultantes, luego ordena las cuentas.

Esto se basa en una respuesta anterior por insin al tener solo un bucle:

function top_words(text, n) {
    // Split text on non word characters
    var words = text.toLowerCase().split(/\W+/)
    var positions = new Array()
    var word_counts = new Array()
    for (var i=0; i<words.length; i++) {
        var word = words[i]
        if (!word) {
            continue
        }

        if (typeof positions[word] == 'undefined') {
            positions[word] = word_counts.length
            word_counts.push([word, 1])
        } else {
            word_counts[positions[word]][1]++
        }
    }
    // Put most frequent words at the beginning.
    word_counts.sort(function (a, b) {return b[1] - a[1]})
    // Return the first n items
    return word_counts.slice(0, n)
}

// Let's see if it works.
var text = "Words in here are repeated. Are repeated, repeated!"
alert(top_words(text, 3))

El resultado del ejemplo es: [['repeat', 3], ['are', 2], ['words', 1]]

Haría exactamente lo que mencionaste anteriormente para aislar cada palabra. Entonces probablemente agregaría cada palabra como el índice de una matriz con el número de ocurrencias como valor.

Por ejemplo:

var a = new Array;
a[word] = a[word]?a[word]+1:1;

Ahora sabes cuántas palabras únicas hay (a.length) y cuántas apariciones de cada palabra existió (a [palabra]).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top