Reputation: 2992
I'm new to learning Scala and would appreciate any thoughts on an idiomatic way to do the following. I want to count occurrences of sequential letter pairs in a word.
For example, for the word "home", the output might be Map("ho"->1,"om"->1,"me"->1)
. And for 'lulu', the result would be Map("lu"->2, "ul"->1 )
.
So performing a simple single-letter count might be done as
"abracadabra".map(s => s).groupBy(identity).mapValues(_.length)
But I'm stumped as to how to add-in the two-letter component of this problem. Thanks for your thoughts.
Upvotes: 3
Views: 228
Reputation: 24812
You can use .sliding
:
scala> "abracadabra".sliding(2).toList.groupBy(identity).mapValues(_.length)
res3: scala.collection.immutable.Map[String,Int] =
Map(br -> 2, ca -> 1, ab -> 2, ra -> 2, ac -> 1, da -> 1, ad -> 1)
scala> "lulu".sliding(2).toList.groupBy(identity).mapValues(_.length)
res4: scala.collection.immutable.Map[String,Int] = Map(ul -> 1, lu -> 2)
From the docs :
Sliding : Groups elements in fixed size blocks by passing a "sliding window" over them
Upvotes: 6
Reputation: 52681
You should use sliding(2)
:
"abracadabra".sliding(2).toVector.map(s => s).groupBy(identity).mapValues(_.length)
// Map(br -> 2, ca -> 1, ab -> 2, ra -> 2, ac -> 1, da -> 1, ad -> 1)
Upvotes: 1