「HELLO WORLD」という文字列があるとすると、文字列内の文字「O」を文字「X」に置き換える関数を呼び出して、新しい文字列が「HELLX WXRLD」のようになる方法はありますか?
6 に答える
どうですか:
let
repl 'o' = 'x'
repl c = c
in map repl "Hello World"
後で追加の文字を置き換える必要がある場合は、repl
関数に句を追加するだけです。
この古いスレッドを取り上げて申し訳ありませんが、ラムダ式を使用しないのはなぜですか?
λ> let replaceO = map (\c -> if c=='O' then 'X'; else c)
λ> replaceO "HELLO WORLD"
"HELLX WXRLD"`
代替案 1 - MissingH の使用
初め:
import Data.List.Utils (replace)
次に使用します。
replace "O" "X" "HELLO WORLD"
代替案 2 - Control.Monad を使用する
1 つの面白い野郎:
import Control.Monad (mfilter)
replace a b = map $ maybe b id . mfilter (/= a) . Just
例:
λ> replace 'O' 'X' "HELLO WORLD"
"HELLX WXRLD"
代替案 3 - if の使用
Amon の提案は、おそらく私が信じる最高のものでした! インポートがなく、読みやすく、理解しやすい!
しかし、うるさいです - セミコロンは必要ありません:
replace :: Eq a => a -> a -> [a] -> [a]
replace a b = map $ \c -> if c == a then b else c
分割統治法を使用した別の解決策を次に示します。
replaceO [] = []
replaceO (x:xs) =
if x == 'O'
then 'X' : replaceO xs
else x : replaceO xs
まず、エッジ条件を設定します"replaceO [] = []"
。
リストが空の場合、置き換えるものはなく、空のリストを返します。
次に、紐を頭と尻尾に分けます。この場合'H':"ELLOWORLD"
、頭が「O」に等しい場合、「X」に置き換えられます。文字列の残りの部分に replaceO 関数を適用します。
head が 'O' と等しくない場合、head を元の位置に戻し、残りの文字列に replaceO 関数を適用します。
If you depend on the text
package (like 99.99% of Haskell applications), you can use T.replace
:
>>> replace "ofo" "bar" "ofofo"
"barfo"
これは使えると思います。
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)