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}