user2336315
user2336315

Reputation: 16067

Scala - List to List of tuples

Beginner here.

Sorry but I did'nt found an answer so I ask the question here.

I want to know how to do this by using the Scala API :

(blabla))( -> List(('(',2),(')',2))

Currently I have this :

"(blabla))(".toCharArray.toList.filter(p => (p == '(' || p == ')')).sortBy(x => x)

Output :

List((, (, ), ))

Now how can I map each character to the tuples I describe ?

Example for a general case :

"t:e:s:t" -> List(('t',2),('e',1),('s',1),(':',3))

Thanks

Upvotes: 1

Views: 2312

Answers (3)

genspire
genspire

Reputation: 136

I like sschaef's solution very much, but I was wondering if anyone could weigh in on how efficient that solution is compared to this one:

scala> val str = "ok:ok:k::"
str: String = ok:ok:k::

scala> str.foldLeft(Map[Char,Int]().withDefaultValue(0))((current, c) => current.updated(c, current(c) + 1)) 
res29: scala.collection.immutable.Map[Char,Int] = Map(o -> 2, k -> 3, : -> 4)

I think my solution is slower. If we have n total occurrences and m unique values:

My solution: we have the fold left over all occurrences or n. For each of these occurrences we look up once to find the current count and then again to create the updated the map. I'm assuming that the creating of the updated map is constant time.
Total complexity: n * 2m or O(n*m)

sschaef's solution: we have the groupBy which I'm assuming just adds entries onto a list without checking the map (so for all values this would be a constant time look up plus appending to the list) so n. Then for the mapValues it probably iterates over the unique values and grabs the size for each key's list. I'm assuming that getting the size of each entry's list is constant time.
Total complexity: O(n + m)

Does this seem correct or am I mistaken in my assumptions?

Upvotes: 0

kiritsuku
kiritsuku

Reputation: 53348

Classic groupBy . mapValues use case:

scala> val str = "ok:ok:k::"
str: String = ok:ok:k::

scala> str.groupBy(identity).mapValues(_.size) // identity <=> (x => x)
res0: scala.collection.immutable.Map[Char,Int] = Map(k -> 3, : -> 4, o -> 2)

Upvotes: 4

arkonautom
arkonautom

Reputation: 958

val source = "ok:ok:k::"
val chars = source.toList
val shorter = chars.distinct.map( c => (c, chars.count(_ == c)))    
//> shorter  : List[(Char, Int)] = List((o,2), (k,3), (:,4))

Upvotes: 4

Related Questions