MrD
MrD

Reputation: 5086

Haskell replace characters in string

Supposing I had the string "HELLO WORLD" is there a way I can call a function that replaces the character 'O' in the string with the character 'X' so that the new string would look like "HELLX WXRLD"?

Upvotes: 22

Views: 48834

Answers (7)

Caio Braga
Caio Braga

Reputation: 11

replace :: Char -> Char -> String -> String
replace _ _ [] = []
replace a b (x : xs) 
                  | x == a = [b] ++ replace a b xs
                  | otherwise = [x] ++ replace a b xs

I'm new to Haskell and I've tried to make it simpler for others like me.

Upvotes: 1

Kutyel
Kutyel

Reputation: 9084

If you depend on the text package (like 99.99% of Haskell applications), you can use T.replace:

>>> replace "ofo" "bar" "ofofo"
"barfo"

Upvotes: 6

Leif Bork
Leif Bork

Reputation: 453

Alternative 1 - Using MissingH

First:

import Data.List.Utils (replace)

Then use:

replace "O" "X" "HELLO WORLD"

Alternative 2 - Using Control.Monad

One funny bastard:

import Control.Monad (mfilter)

replace a b = map $ maybe b id . mfilter (/= a) . Just

Example:

λ> replace 'O' 'X' "HELLO WORLD"
"HELLX WXRLD"

Alternative 3 - Using if

Amon's suggestions was probably the finest I believe! No imports and easy to read and understand!

But to be picky - there's no need for semicolon:

replace :: Eq a => a -> a -> [a] -> [a]
replace a b = map $ \c -> if c == a then b else c

Upvotes: 19

itsthenewmeta
itsthenewmeta

Reputation: 1

I guess this could be useful.

main = print $ charRemap "Hello WOrld" ['O','o'] ['X','x']

charRemap :: [Char] -> [Char] -> [Char] -> [Char]
charRemap [] _ _ = []
charRemap (w:word) mapFrom mapTo =
    if snd state
        then mapTo !! fst state : charRemap word mapFrom mapTo
        else w : charRemap word mapFrom mapTo
    where
        state = hasChar w mapFrom 0

hasChar :: Char -> [Char] -> Int -> (Int,Bool)
hasChar _ [] _ = (0,False)
hasChar c (x:xs) i | c == x = (i,True)
                   | otherwise = hasChar c xs (i+1)

Upvotes: -2

Arnon
Arnon

Reputation: 2237

Sorry for picking up this old thread but why not use lambda expressions?

λ> let replaceO = map (\c -> if c=='O' then 'X'; else c)
λ> replaceO "HELLO WORLD"
"HELLX WXRLD"`

Upvotes: 16

Iceandele
Iceandele

Reputation: 660

Here's another possible solution using divide and conquer:

replaceO [] = []
replaceO (x:xs) = 
     if x == 'O' 
     then 'X' : replaceO xs 
     else x : replaceO xs

First, you set the edge condition "replaceO [] = []".
If the list is empty, there is nothing to replace, returning an empty list.

Next, we take the string and divide it into head and tail. in this case 'H':"ELLOWORLD"
If the head is equal to 'O', it will replace it with 'X'. and apply the replaceO function to the rest of the string.
If the head is not equal to 'O', then it will put the head back where it is and apply the replaceO function to the rest of the string.

Upvotes: 1

Ingo
Ingo

Reputation: 36329

How about:

let 
    repl 'o' = 'x'
    repl  c   = c
in  map repl "Hello World"

If you need to replace additional characters later, just add clauses to the repl function.

Upvotes: 41

Related Questions