Count of words in a mutable Map The function should get some text on input and return a map in a following format:

("word1" -&gt; 1, "word2" -&gt; 2 ...)


The keys are words from text and the values are representing the number of times the word appeared in the text. We take into a count only words which at least 4 characters long. Special chars are ignored, words are case insensitive.

import scala.collection.mutable.Map

def wordCounter(text: String) = {
  var map:Map[String, Int] = Map()

  text.toLowerCase.replaceAll("[^a-z ]", "").split(" ").filter(_.length &gt; 3).foreach(x =&gt; addWord(map, x))
  map
}

def addWord(map: Map[String, Int], word: String) = {
  map(word) = map.getOrElse(word, 0) + 1
}



Is that fine to use mutable in this case?
Should I always be suspicious about the solutions that require to use mutable and use it only when its problematic to implement it with immutable types?
I'm doing an extra loop to filter words longer than 3 chars. In my mind this way it looks a bit cleaner than to have a condition in foreach. Should I care more about the performance or readability in my code?
Should I always be suspicious about the solutions that require to use mutable and use it only when its problematic to implement it with immutable types?


I'm new to Scala myself, but I would say yes.
Try to use immutable and elegant solutions when possible, but it's OK to resort to mutable alternatives as a second choice.


  Is that fine to use mutable in this case?


I would use an immutable algorithm in this case: 


use .groupBy to create groupings
use .map to convert the groupings to a list of word-count pairs
a final .toMap call and the map is ready



  I'm doing an extra loop to filter words longer than 3 chars. In my mind this way it looks a bit cleaner than to have a condition in foreach. Should I care more about the performance or readability in my code?


If the complexity is on the same order, then prefer readability, even if slightly slower. For example, it's OK to choose an \$O(3n)\$ algorithm instead of an \$O(2n)\$ algorithm. When code is more readable, it tends to be also easier to optimize at a higher level of logic, which can lead to far faster solutions than the original alternatives.

Suggested implementation using immutable logic:

  def wordCounter(text: String) = {
    {
      for {
        word &lt;- text.toLowerCase.replaceAll("[^a-z ]", "").split(" ")
        if word.length &gt; 3
      } yield word
    }.groupBy(identity).map { case (word, list) =&gt; (word, list.length) }
  }