How to keep track of word count in text file

454 Views Asked by At

I'm trying to count the occurrences of every word within a text file (case insensitive) and store the words and their counts in a list.

This is my object class for the every word to be stored in the list,

public class WordItem
{
    public string Word { get; set; }
    public int Count { get; set; }
}

and my code function to parse the text files

public List<WordItem> FindWordCount()
{
    //I've successfully parsed the text file into a list
    //of words and stripped punctuation up to this point
    //and stored them in List<string> wordlist.

    List<string> wordlist;
    List<WordEntry> entries = new List<WordEntry>();

    foreach (string word in wordlist)
    {
        WordItem temp = new WordItem();
        temp.Word = word;
        temp.Count = 1;
        entries.Add(temp);
    }
}

How can I edit my word count function to prevent duplicates words in the list, and instead increment the count value everytime I find the word an additional time?

3

There are 3 best solutions below

11
On BEST ANSWER

I would use a Dictionary with a case insensitive string-comparer:

public IEnumerable<WordItem> FindWordCount(IEnumerable<string> wordlist)
{
    var wordCount = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
    foreach (string word in wordlist)
    {
        int count = 0;
        bool contained = wordCount.TryGetValue(word, out count);
        count++;
        wordCount[word] = count;
    }
    foreach (var kv in wordCount)
        yield return new WordItem { Word = kv.Key, Count = kv.Value };
}

You can use it in this way:

var wordList = new string[] { "A", "a", "b", "C", "a", "b" };
var wordCounts = FindWordCount(wordList).ToList();
0
On

There are also pretty single-line solutions:

IEnumerable<WordItem> countedList = wordlist.Distinct().Select(word => new WordItem() { Word = word, Count = wordlist.Count(compWord => word.Equals(compWord, StringComparison.InvariantCultureIgnoreCase)) });

or, if you prefer a dictionary, in order to be able to search for specific words later:

Dictionary<string, int> dictionary = wordlist.Distinct().ToDictionary<string, string, int>(word => word, word => wordlist.Count(compWord => word.Equals(compWord, StringComparison.InvariantCultureIgnoreCase)));

Performance is of course a bit less than Tim Smelters solution, because of the Count()-Call (which leads to O(n^2)) but using C# 6.0 you'd be able to write down the method with a lambda expression for definition instead of a body.

1
On

Simple and with your types:

public string[] wordList;

public class WordItem
{
    public string Word { get; set; }
    public int Count { get; set; }
}

public IEnumerable<WordItem> FindWordCount()
{
  return from word in wordList
         group word by word.ToLowerInvariant() into g
         select new WordItem { Word = g.Key, Count = g.Count()};
}