rel1x
rel1x

Reputation: 2441

Filter by length

How I can make here filter (x:xs) = (x, length (x:xs)) that puts length when length > 1?

Currently, if input is abcaaabbb output is [('a',1),('b',1),('c',1),('a',3),('b',3)], but I'm looking for abca3b3.

My code:

import Data.List

encode :: [Char] -> [(Char, Int)]
encode s = map go (group s)
               where go (x:xs) = (x, length (x:xs))

main = do
    s <- getLine
    print (encode s) 

Last string will be putStrLn (concat (map (\(x,y) -> x : [y]) (encode s))) for convert list to string.

Upvotes: 0

Views: 671

Answers (3)

Izabel
Izabel

Reputation: 191

Not sure if this suits your needs, but if you do not need filtering, this does the work:

encode::String -> String
encode "" = ""
encode (x:xs) = doIt0 xs x 1 where
        doIt0 [] ch currentPos = [ch]++showPos currentPos
        doIt0 (x:xs) ch currentPos
                |x==ch = doIt0 xs ch $ currentPos+1
                |otherwise= [ch]++ (showPos currentPos) ++ (doIt0 xs x 1)
        showPos pos = if pos> 1 then show pos else ""

main = do
        s <- getLine
        print (encode s)                

Upvotes: 0

quant
quant

Reputation: 2224

You can't have a list like this in Haskell:

[('a'),('b'),('c'),('a',3),('b',3)]

Each element if a list needs to have the same type in haskell, and ('c') [('a') :: Char] and ('b',3) [('a',1) :: Num t => (Char, t)] are different types.

Maybe also have a look at List of different types?

I would suggest, that you change your list to a (Char, Maybe num) datastructure.

Edit:

From your new question, I think you have been searching for this:

import Data.List

encode :: [Char] -> [(Char, Int)]
encode s = map go (group s)
               where go (x:xs) = (x, length (x:xs))

f :: (Char, Int) -> String
f (a, b) = if b == 1 then [a] else [a] ++ show b

encode2 :: [(Char, Int)] -> String
encode2 [] = []
encode2 (x:xs) = f(x) ++ encode2 xs

main = do
    s <- getLine
    putStrLn $ encode2 $ encode s

Upvotes: 1

tokosh
tokosh

Reputation: 1836

As I am a newbie myself, this is probably not very haskellian. But you can do it about like this (xs as would be the list [('a', 1), ('b', 2), ('a', 3)]):

Create "a1b2a3":

concat $ map (\(c, l) -> c:(show l)) xs

Filter out 1s:

filter (\x -> x /= '1') "a1b2a3"

will give you "ab2a3"

Upvotes: 2

Related Questions