Какой самый лучший и самый эффективный способ подсчета ключевых слов в JavaScript? По сути, я хотел бы взять строку и получить первые N слов или фраз, которые встречаются в строке, в основном для использования предлагающих тегов. Я ищу больше концептуальных подсказок или ссылок на реальные примеры, чем реальный код, но я, конечно, не возражал бы, если бы вы тоже захотели поделиться кодом. Если есть определенные функции, которые могут помочь, я бы тоже был признателен.
Прямо сейчас я думаю, что использую функцию split () для разделения строки пробелами, а затем очищаю знаки препинания с помощью регулярного выражения. Я бы также хотел, чтобы он был нечувствительным к регистру.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Попробуйте разделить строку на слова и посчитать полученные слова, а затем отсортировать по счетам.
После того, как вы очистили этот массив слов и, скажем, вы назвали его 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");
}
Это должно дать вам основы выполнения этой части работы.
Вырезать, вставить + выполнить демо:
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"));
Многоразовая функция:
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;
}
Блин, у тебя должно быть намного больше свободного времени, чем у меня! Могу я прислать вам какую-нибудь работу? ;) J / K Просто доставляю вам неприятности, потому что вы в основном дали этому парню полный рабочий код, а не просто несколько кусочков (как я). Заставь парня изобразить что-нибудь самостоятельно!
Это заняло всего несколько минут. На пару минут дольше, чем следовало бы, так как я выполняю обязанности «тихо сижу в темноте и слушаю, как ребенок просыпается в соседней комнате», поэтому все время опечатываю :)
@insin Вау, спасибо. Намного больше, чем я ожидал, но он послужит отличной точкой отсчета. @Jason Я пишу класс MooTools с еще несколькими параметрами, так что еще немного поработать. Хотя insin определенно помог.
Я бы сделал именно то, что вы упомянули выше, чтобы изолировать каждое слово. Затем я бы, вероятно, добавил каждое слово в качестве индекса массива с количеством вхождений в качестве значения.
Например:
var a = new Array;
a[word] = a[word]?a[word]+1:1;
Теперь вы знаете, сколько уникальных слов существует (a.length) и сколько появлений каждого слова существовало (a [word]).
Это не сработает - вы действительно используете здесь массив как объект, а не как массив. Добавление свойств в такой массив обновит только указанную длину массива, если свойство является числовым.
Это основано на предыдущем ответе инсин, имея только один цикл:
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))
Результат примера: [['repeated',3], ['are',2], ['words', 1]]
Конечно, я бы нашел время, чтобы опубликовать полное решение, но у меня есть работа, и мне нужно получить деньги! :) Кроме того, это в любом случае для меня самая интересная часть (что на самом деле не так уж и интересно) - остальное - легкие вещи.