Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution #50

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions CountingWords.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
class WordCounter {

// When we make a new WordCounter, create
// a variable to hold the data from the
// file we're going to open.
constructor () {
this.data = ""
}

openFile(filename) {

// Use the Node file system module, fs.
const fs = require('fs');

// Use the fs.readFileSync method to read speech.txt.
this.data = fs.readFileSync('speech.txt', 'utf8')
}

analyzeFile() {

// Create a dictionary object to keep track of
// all the words in the text and how many times
// each one appears.
let dictionary = {}

// Create an array of the words in the file, using
// regex to return things that are actually words,
// that is, made up of capital or lowercase letters
// A to Z or an apostrophe and having one or more
// characters.
const words = this.data.match(/[A-Za-z']+/g)


// Iterate through the words from the text...
for (let i = 0; i < words.length; i++) {

// If it's already in our dictionary,
// add one to the count.
if (words[i] in dictionary)
dictionary[words[i]]++
// Otherwise, add this word to our
// dictionary with a count of one.
else
dictionary[words[i]] = 1
}

// Next, move our dictionary information over
// to an array so we can sort it by the number
// of appearances of each word.

let output = []

for (const word in dictionary)
output.push(dictionary[word] + " - " + word)

// Sort the array and then print the results.
//
// I use a little regex magic to sort primarily
// by the number at the beginning of each string
// (descending) and then secondarily by the text
// content (ascending). The regex for the first
// part of the match returns one or more digits
// at the beginning of the string. The regex
// for the secondary sort first takes the lower
// case version of the string (because we don't
// care about case) and then returns one or more
// lower case letters from a to z or the
// apostrophe. Then the ternary makes the
// secondary comparison return 1 if the first
// word is first alphabetically or -1 if the first
// word is last alphabetically.
//
// The logical or here makes it so we only look at
// the second part of the comparison if the value
// of the first part is zero.

output.sort((a,b) => b.match(/^\d+/) - a.match(/^\d+/) ||
(a.toLowerCase().match(/[a-z']+/) >
b.toLowerCase().match(/[a-z']+/) ? 1 : -1))

// I use the join method to print each element
// of the sorted array on a new line with the
// \n character.
return output.join('\n')
}
}

// Create a new instance of WordCounter.
const counter = new WordCounter()

// Use this new WordCounter called counter
// to open the file we want to analyze.
counter.openFile("speech.txt")

// Call the analyzeFile method and log
// the reponse to the console.
console.log(counter.analyzeFile())