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 <- text.toLowerCase.replaceAll("[^a-z ]", "").split(" ")
if word.length > 3
} yield word
}.groupBy(identity).map { case (word, list) => (word, list.length) }
}