Counting Words with Elixir

I wanted to play with transforming some data and a couple data types in elixir.

So I tried my hand at the word count problem. Given a string containing > 0 words, return a Map with the words as keys and their number of occurrences in the string as their value.

First I got my project setup using Mix

mix new word_count

When I think of a problem like this I like to break it down into steps. In elixir this leads naturally into taking advantage of the pipe operator |>

The steps I wanted were convert to a list of words, then add the words into a map dictionary as keys incrementing their value.

Now that I had my steps I could define it in elixir.

  def count(sentence) do
    sentence
    |> String.split
    |> count
  end

Using a guard clause I created another count definition that has a different signature.

  def count(words) when is_list(words) do
    Enum.reduce(words, %{}, &update_count/2)
  end

The above Enum.reduce was a bit tricky for me, as working with an accumulator I haven't done before. Basically what this does is, loop through the list. In this case words. Send each item to a function as well as the accumulator itself. Then store the return of the function back into the accumulator for the next item in the list. Finally returning the accumulator once the list is empty.

That brings me finally to the helper function update_count/2

  def update_count(word, acc) do
    Map.update acc, String.to_atom(word), 1, &(&1 + 1)
  end

This one is pretty straight forward. Takes in a dictionary, a key, an initial value for that key, if there is a value present for that key already then runs the function given; in this case adding 1 to the value.

Can find the full mix project on github

I'll need to run a number more of these exercises to get this all locked in!