2014-10-20 176 views
2

我想編寫一個接受字符串的Haskell函數,並用特殊代碼%20替換任何空格字符。例如:如何用「%20」替換字符串中的空格字符?

sanitize "http://cs.edu/my homepage/I love spaces.html" 
-- "http://cs.edu/my%20homepage/I%20love%20spaces.html" 

我在考慮使用concat函數,所以我可以連接一個列表到一個普通列表。

+3

你可能想看看concatMap。 – 2014-10-20 04:17:10

回答

1
changer :: [Char] -> [Char] -> [Char] 
changer [] res = res 
changer (x:xs) res = changer xs (res ++ (if x == ' ' then "%20" else [x])) 

sanitize :: [Char] -> [Char] 
sanitize xs = changer xs "" 

main = print $ sanitize "http://cs.edu/my homepage/I love spaces.html" 
-- "http://cs.edu/my%20homepage/I%20love%20spaces.html" 

sanitize功能的目的是爲了只調用changer,來完成實際的工作。現在,changer遞歸調用自身,直到當前字符串耗盡。

changer xs (res ++ (if x == ' ' then "%20" else [x])) 

它以第一個字符x並檢查它是否等於" ",如果是的話給人%20,否則實際的字符本身作爲一個字符串,然後我們用積累的字符串拼接。

注意:這可能不是最佳解決方案。

+0

謝謝你的幫助。任何想法如何使用concat? – wadbarca 2014-10-20 03:09:35

+0

@WaleedAldeghaither'++'是concat操作符。 – thefourtheye 2014-10-20 03:10:28

+0

是的,我的意思是concat函數 – wadbarca 2014-10-20 03:12:22

3

你正在尋找的高階函數是

concatMap :: (a -> [b]) -> [a] -> [b] 

在你的情況下,選擇a ~ Char, b ~ Char(和觀察到String僅僅是[Char]一種代名詞),我們得到

concatMap :: (Char -> String) -> String -> String 

所以一旦你寫了一個功能

escape :: Char -> String 
escape ' ' = "%20" 
escape c = [c] 

你c一個電梯,要僅通過寫

sanitize :: String -> String 
sanitize = concatMap escape 
+1

太棒了!我喜歡你的方式,這讓我明白它很強大,而且很簡單。問候:) – wadbarca 2014-10-20 08:28:00

2

使用的理解也適用在字符串的工作,具體如下,

changer :: [Char] -> [Char] 
changer xs = [ c | v <- xs , c <- if (v == ' ') then "%20" else [v] ] 
0

可以使用intercalate功能從Data.List模塊。它用給定的分隔符和列表執行intersperse,然後連接結果。

sanitize = intercalate "%20" . words 

或使用模式匹配:

sanitize [] = [] 
sanitize (x:xs) = go x xs 
      where go ' ' []  = "%20" 
        go y []  = [y] 
        go ' ' (x:xs) = '%':'2':'0': go x xs 
        go y (x:xs) = y: go x xs 
+1

'插入「%20」。單詞'不太合適,因爲'單詞'去除了前後空格,將連續空格修剪成單個空格,並使用'isSpace',它比'(=='')'少挑剔。 – dfeuer 2014-10-20 20:39:36

0

Shanth的模式匹配方法的另一種表達:

sanitize = foldr go [] 
    where 
    go ' ' r = '%':'2':'0':r 
    go c r = c:r