Home > OS >  How can i count occurrences in a list using this function in scala
How can i count occurrences in a list using this function in scala

Time:05-27

I've found multiple ways of doing this already but haven't been able to apply those here since i'm not familiar with the language yet, so maybe a more direct question could help

   def occurrences(cars: List[Char]): List [(Char, Int)] = {
    
    . . .

  }

Thanks in advance!

CodePudding user response:

If you are not familiar with the language, this answer will probably not help you very much ... but then, it's not very likely that another will. My advice to you would be to grab a book and learn the basics of the language first, before jumping into asking other people to solve random made up problems for you.

As to counting characters in a string, it would be something like this:

chars.groupBy(identity).mapValues(_.size).toList

CodePudding user response:

As both answers here show, there are plenty of ways to solve this using the stdlib; as I always say the Scaladoc is your friend.
Also, as both answers suggest, it is recommended that you learn the language.

However, I wanted to show another cool way of solving this problem using cats.

import cats.syntax.all._

chars.foldMap(char => Map(char -> 1))

foldMap is a function added by cats to the List[Char] that as the name suggests does mapping and folding in the same step.
The folding is done using the default combine operation of the type returned by the map. And the default combine operation of a Map is to join both maps and combine values with matching keys using their default combine operation; and for ints that is sum.

CodePudding user response:

First of all, cars is not a good name for a list of characters :) (I know, just kidding). You should definitely get more into the language and read more about some of the most used functions, like what they are, what they do and why they exist, but just to answer this specific question, you can do this:

Approach No.1:
  def occurrences(chars: List[Char]): List[(Char, Int)] =
    chars.foldLeft(Map.empty[Char, Int])(
      (occurrencesMap, newChar) => occurrencesMap.updatedWith(newChar) {
        case Some(count) => Some(count   1)
        case None => Some(1)
      }
    ).toList
Explanation:

Basically we're just iterating over the list, and we want to aggregate the data in a structure, where a character is mapped to its number of usages, so we use a Map[Char, Int], and during the iteration, if the aggregator (occurrencesMap in this case) contains the char, we increment it and otherwise we initiate it with 1.

Approach No.2:

I can also suggest this one-line approach, but I think the first approach is more beginner-friendly or understandable in some senses:

def occurrences(chars: List[Char]): List[(Char, Int)] =
    chars.groupMapReduce[Char, Int](identity)(_ => 1)(_   _).toList
Explanation:

As the function name declares groupMapReduce first groups the values inside the list by a function, then maps each key occurrence into a value, and then reduce the resulted values for each key, into a single item, so we use identity to group the items inside the list, by the value of the character itself, and if a character is found, we basically just found 1 character right? so ignore the value of the character, and just return 1 :D _ => 1, and at the end, you would have something like 'c' -> List(1, 1, 1), so let's just add them all together, or use .length to count the occurrences.

  • Related