Reputation: 13
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
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
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