Generowanie mapy częstotliwości dla ciągu w Scali

Powiedzmy, że mam ciąg „hello” i chcę wygenerować mapę częstotliwości znaków:

Map[Char,Int] = Map(h -> 1, e -> 1, o -> 1, l -> 2)

Mógłbym to zrobić iteracyjnie:

val str = "hello"
var counts = new scala.collection.mutable.HashMap[Char,Int]
for (i <- str) {
    if (counts.contains(i))
        counts.put(i, counts(i) + 1)
    else
        counts.put(i, 1)
}

Przez zamieszanie w REPL odkryłem, że potrafię zrobić coś bardziej zwięzłego i nie używać zmiennej kolekcji:

> str.groupBy(_.toChar).map{ p => (p._1, p._2.length)}
scala.collection.immutable.Map[Char,Int] = Map(h -> 1, e -> 1, o -> 1, l -> 2)

Ale nie wiem o charakterystyce wydajności groupBy () ani o tym, co dzieje się w bloku przekazywanym do mapy (jak co, dokładnie, p).

Jak zrobić to idiomatycznie, używając funkcjonalnych paradygmatów w Scali?

W tle, po raz pierwszy przyjeżdżam do Scali z Ruby. W Ruby użyłbyminject ale nie jestem pewien, jaki jest równoległy sposób, aby to zrobić w Scali:

counts = str.each_byte.inject(Hash.new(0)){ |h, c| h[c] += 1; h}

questionAnswers(4)

yourAnswerToTheQuestion