Reputation: 397
I have a string "AB0123456789"
and the output I would like to have is: "AB01 2345 6789"
... I want to add a space after every fourth character. How can I do this?
Main> addSpace "AB0123456789"
"AB01 2345 6789"
Upvotes: 1
Views: 8169
Reputation: 54058
I would think pattern matching would make this easiest:
addSpaces :: String -> String
addSpaces xs@(_:_:_:_:[]) = xs
addSpaces (a:b:c:d:xs) = a:b:c:d:' ':addSpaces xs
addSpaces xs = xs
You have to include the first case so you don't potentially get a space at the end, but it's pretty straightforward. This isn't extensible, though, you wouldn't be able to use a function like this to dynamically choose how many characters you want to skip before inserting a space (such as in @cdk's answer)
Upvotes: 3
Reputation: 664599
With Data.List.intercalate
and Data.List.Split.chunksOf
this is easy:
import Data.List.Split
addSpace :: String -> String
addSpace = intercalate " " . chunksOf 4
Upvotes: 14
Reputation: 144136
window :: Int -> [a] -> [[a]]
window i = unfoldr (\l -> if null l then Nothing else Just (splitAt i l))
addSpace :: String -> String
addSpace = intercalate " " . window 4
Upvotes: 1
Reputation: 48664
This may not be the most efficient:
addSpace xs = if length xs <= 4
then xs
else take 4 xs ++ " " ++ addSpace (drop 4 xs)
Demo in ghci:
ghci > addSpace "AB0123456789"
"AB01 2345 6789"
Upvotes: 5
Reputation: 6778
You can use splitAt
. Heres a function that adds space after every nth character.
spaceN :: Int -> String -> String
spaceN n = init . go
where go [] = []
go xs = let (as, bs) = splitAt n xs in as ++ (' ' : go bs)
for your specific case:
λ. spaceN 4 "AB0123456789"
"AB01 2345 6789"
Upvotes: 1