I'm an elixir beginner. I'm doing the word count exercise of exercism website. The word count exercise returns a map with the word as the key and the number of instances as value. The exercise excludes special characters, and ignores underscores. My code works, but I'm sure there is a way to make it cleaner. I've attached the test file so that you can see the criteria that it needs to pass.
word_count.exs
defmodule Words do
@doc """
Count the number of words in the sentence.
Words are compared case-insensitively.
"""
@spec count(String.t) :: map
def count(sentence) do
String.downcase(sentence) |>
String.split(~r/[\s_]/) |>
Enum.filter(fn(word) -> String.match?(word, ~r/[a-zA-z\d]/) end) |>
Enum.map(fn(word) -> String.replace(word, ~r/[:!&@$%^,]/, "") end)|>
Enum.group_by(fn(word) -> word end) |>
Enum.reduce(%{}, fn({k, v}, acc) -> Map.put(acc, k, Enum.count(v)) end)
end
end
word_count_test.exs
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
Code.load_file("word_count.exs")
end
ExUnit.start
ExUnit.configure exclude: :pending, trace: true
defmodule WordsTest do
use ExUnit.Case
test "count one word" do
assert Words.count("word") == %{ "word" => 1 }
end
test "count one of each" do
expected = %{ "one" => 1 , "of" => 1 , "each" => 1 }
assert Words.count("one of each") == expected
end
test "count multiple occurrences" do
expected = %{ "one" => 1 , "fish" => 4 , "two" => 1 , "red" => 1 , "blue" => 1 }
assert Words.count("one fish two fish red fish blue fish") == expected
end
test "ignore punctuation" do
expected = %{"car" => 1, "carpet" => 1, "as" => 1, "java" => 1, "javascript" => 1}
assert Words.count("car : carpet as java : javascript!!&@$%^&") == expected
end
test "include numbers" do
expected = %{"testing" => 2, "1" => 1, "2" => 1}
assert Words.count("testing, 1, 2 testing") == expected
end
test "hyphens" do
expected = %{"co-operative" => 1}
assert Words.count("co-operative") == expected
end
test "ignore underscores" do
expected = %{"two" => 1, "words" => 1}
assert Words.count("two_words") == expected
end
test "normalize case" do
expected = %{"go" => 3}
assert Words.count("go Go GO") == expected
end
test "German" do
expected = %{"götterfunken" => 1, "schöner" => 1, "freude" => 1}
assert Words.count("Freude schöner Götterfunken") == expected
end
end