0
\$\begingroup\$

I'm trying to re-learn some JS fundamentals and wondered if anyone knowledgabe could tell me if I'm doing something very wrong in my approach to this simple word counting class.

I want to create a class that takes arbitrary text and returns information about its wordcount, frequency of words, etc. One of the methods I have so far returns a hash where each key coresponding to a word has an element called count which is its frequency in the text.

One usage is to produce an output that will be printed to a file with WORD COUNT on each line.

function WordCounter(){
   this.text = new String()
}

WordCounter.prototype.addWords = function(words){
    this.text += words
}

WordCounter.prototype.count = function(){
    return this.text.split(" ").length
}
WordCounter.prototype.getFrequenciesAsHash = function(){
    var words = this.text.split(" ")
    var frequencies = {}
    while(words.length > 0){
        var word = words.pop()
    if(typeof frequencies[word] == "undefined"){
        frequencies[word] = {}
        frequencies[word].count = 0
    }
    frequencies[word].count++
    }
    return frequencies
}
\$\endgroup\$
  • \$\begingroup\$ I am not sure what you are trying to do really... \$\endgroup\$ – Naftali aka Neal Jul 17 '13 at 21:11
  • \$\begingroup\$ Thanks for looking. I guess I could have described better. I want to create a class that takes arbitrary text and returns information about its wordcount, frequency of words, etc. One of the methods I have so far returns a hash where each key coresponding to a word has an element called count which is its frequency in the text. \$\endgroup\$ – maninjeans Jul 17 '13 at 21:14
  • \$\begingroup\$ @maninjeans: Go ahead and edit that into the question for everyone else to see. \$\endgroup\$ – Jamal Jul 17 '13 at 21:16
  • \$\begingroup\$ @jamal man you guys are fast, edited in as you typed :) \$\endgroup\$ – maninjeans Jul 17 '13 at 21:18
  • \$\begingroup\$ @maninjeans: I have a lot of free time. :-) \$\endgroup\$ – Jamal Jul 17 '13 at 21:20
3
\$\begingroup\$

Conceptually, I feel like you are doing this backwards. You should be storing an array of strings instead of repeatedly splitting a string into an array.

Here's my take on it:

function WordCounter(){
   this.words = []; // You should just use an array. It makes more sense here.
}

WordCounter.prototype.addWords = function(){
    // this allows you to pass in words as multiple arguments, or as an array of words
    // i.e.: 
    // myWordCounter.addWords(["one","two","three"]); 
    // or 
    // myWordCounter.addWords("one", "two", "three");
    this.words = this.words.concat([].slice.call(arguments));
}
WordCounter.prototype.count = function(){
    return this.words.length;
}
WordCounter.prototype.toString = function(){
    //this replaces the text property
    return this.words.join(" ");
}
WordCounter.prototype.getFrequenciesAsHash = function(){
    // reduce is much more elegant here. 
    // if you have to support older browsers, just use a shim to fill in array method support
    return this.words.reduce(function(hash, word){
        // no need to do a typeof.
        if(hash[word] === undefined) 
            hash[word] = 0; // no reason to create an object

        hash[word]++;

        return hash;
    }, {});
}

If you want to be able to add words from a multi-word string, I would suggest a separate method for clarity:

WordCounter.prototype.extractWords = function(string){
    this.addWords(string.match(/\w+/g));
}

The naming could be better.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks, I was thinking the same thing yesterday, that I sould maintain an array of strings instead of creating one each time the getFrequencies is called, but I was unsure how to best go about it. The reduce method also seems to be the way to go. I'll play around with this tonight. \$\endgroup\$ – maninjeans Jul 18 '13 at 7:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.