TWallner
TWallner

Reputation: 13

Scala: Frequency of characters in a list

I am a novice programmer from a python/java background, who is trying to get to grips with functional programming in scala. I am trying to write a function that will take a list of characters and return a list of their frequencies. For example, List('a','b','a') should return List(('a', 2), ('b', 1)). I am new to scala and tail recursion, so please don't presume much prior knowledge :) Here is what I have:

def times(chars: List[Char]): List[(Char, Int)] = {

  def loop(chars: List[Char], list: List[(Char, Int)]): List[(Char, Int)] =
  {
    if (chars.isEmpty) list
    else
    {
      val head = chars.head
      val freq = chars.count(x=> x == head)
      (head,freq) :: list
      loop(chars.tail.filterNot(x=> x == head),list)
    }
  }
  loop(chars,List())
}

If I run times(List('a','b','a')) I just get an empty list. Any help would be greatly appreciated!

Upvotes: 1

Views: 632

Answers (2)

SandeepGodara
SandeepGodara

Reputation: 1528

While the accepted answer is good enough for the question; some addition for learning:: while processing List items you can/should take advantage of pattern matching like below

def loop(chars:List[Char], list:List[(Char,Int)]):List:[(Char,Int)]= chars match{
case head::tail => val freq = chars.count(x=> x == head)
loop(tail.filterNot(x=> x == head), (head, freq)::list)
case Nil => list
}

Upvotes: 1

Levi Ramsey
Levi Ramsey

Reputation: 20551

List is immutable so

(head, freq) :: list

creates a new List with (head, freq) at the front of that list (because List is immutable, however, it's safe for the tail of the new list to be the same object as list). Because you don't assign the new list to anything, that line may as well not happen.

Something like:

val nextList = (head, freq) :: list
loop(chars.tail.filterNot(x => x == head), nextList)

will result in the list getting built up in loop.

Upvotes: 1

Related Questions