Skip to content

Instantly share code, notes, and snippets.

@escottalexander
Created May 4, 2018 22:00
Show Gist options
  • Save escottalexander/89bf11ccfab9af7902d2e3739cfc1064 to your computer and use it in GitHub Desktop.
Save escottalexander/89bf11ccfab9af7902d2e3739cfc1064 to your computer and use it in GitHub Desktop.
function getTokens(rawString) {
// NB: `.filter(Boolean)` removes any falsy items from an array
return rawString.toLowerCase().split(/[ ,!.";:-]+/).filter(Boolean).sort();
}
function mostFrequentWord(text) { // define the function. It accepts one argument, "text"
let words = getTokens(text); // set a variable, "words", to the filtered and sorted output of "getTokens". It is an array of all the words present in "text"
let wordFrequencies = {}; // create an object, "wordFrequencies", to keep track of word quantities
for (let i = 0; i <= words.length; i++) { // begin for loop
if (words[i] in wordFrequencies) { // it checks if the key representing the current word exists in our object
wordFrequencies[words[i]]++; // if it exists, add 1 to the count for that word
} else { // if not...
wordFrequencies[words[i]] = 1; // it creates the key and sets the value to 1
}
}
let currentMaxKey = Object.keys(wordFrequencies)[0]; // set the new variable, "currentMaxKey" to the first key in "wordFrequencies"
let currentMaxCount = wordFrequencies[currentMaxKey]; // set "currentMaxCount" to express the value of the max key
for (let word in wordFrequencies) { //for loop begins
if (wordFrequencies[word] > currentMaxCount) { // if the current words count is greater than "currentMaxCount"
currentMaxKey = word; // switch it so that this word holds the rank as the one with the highest count
currentMaxCount = wordFrequencies[word]; // also switch "currentMaxCount" to express this new leaders count
}
}
return currentMaxKey; //return the word with the highest count
}
@Jefftopia
Copy link

Jefftopia commented May 6, 2018

Solid work. A couple things I noticed.

if (words[i] in wordFrequencies) { // it checks if the key representing the current word exists in our object
Object.prototype.hasOwnProperty() is to be preferred to in. In your case, you're fine, because you're using a plain-old-javascript-object (POJO). I'm leaving this just as a helpful FYI.

let words = getTokens(text);
let wordFrequencies = {};

You should use const over let if you don't intend to reassign the variable. While let prevents accidentally using the same variable name twice in a scope, const does this while also protecting you from accidentally overriting a variable.

Overall, you can simplify your approach by using just one for-loop. You can create a variable for max and maxKey. Start by setting max to 0, and maxKey to an empty string. On each iteration of the loop, after ++ or = 1, check if wordFrequencies[words[i]] > max. If so, set max equal its value, and set maxKey equal to the word. I outline this approach below.

for (const w of words) {
	if (dict.hasOwnProperty(w)) {
		dict[w] = 1;
	} else {
		dict[w]++;
	}

	const c = dict[w];
	if (c > max) {
		max = c;
		maxKey = w;
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment