How can I count the frequency of characters in a string and then output them in sort of a table?
For example, if I input the word "happy" the result would be
h 1
a 1
p 2
y 1
If this could be ordered in ASCII order too that would be brilliant.
I know I need to use the count function, any other hints would be appreciated.
EDIT: All the answers are brilliant, only I'm such a beginner at Haskell that I don't actually understand what they are doing.
The simplest solution is to use a Data.Map
to store the intermediate mapping from character to frequency. You can then construct the counts easily using fromListWith
. Since Data.Map
is sorted, you get them in ASCII order for free.
λ> :m + Data.Map
λ> let input = "happy"
λ> toList $ fromListWith (+) [(c, 1) | c <- input]
[('a',1),('h',1),('p',2),('y',1)]
So what's happening here?
The idea is to build a Data.Map
(a tree map) using the characters as keys and the frequencies as values.
First, we take the input string and make tuples of each character with a 1
to indicate one occurrence.
λ> [(c, 1) | c <- input]
[('h',1),('a',1),('p',1),('p',1),('y',1)]
Next, we use fromListWith
to build a sorted map from these key-value pairs by repeatedly inserting each key-value pair into a map. We also give it a function which will be used when a key was already in the map. In our case, we use (+)
so that when a character is seen multiple times, we add the count to the existing sum.
Finally we covert the map back into a list of key-value tuples using toList
.
There's probably something shorter, but this works:
Prelude> import Data.List
Prelude Data.List> map (\x -> (head x, length x)) $ group $ sort "happy"
[('h',1),('a',1),('p',2),('y',1)]
func xs = map (\a -> (head a, length a)) $ group $ sort xs
Use list comprehension, no need for any imports or sorting.
[ (x,c) | x<-['A'..'z'], let c = (length.filter (==x)) "happy", c>0 ]
Result:
[('a',1),('h',1),('p',2),('y',1)]
Above is the filtered and rewritten (only character with count > 0) from:
[(x,(length.filter (==x)) "happy" ) | x<-['A'..'z']]
Explanation:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With