[英]Split string to a list of strings in Clean
由於資源有限,我需要在這里提出一個問題。 我一直在努力進行函數式編程,無休止的Haskell教程並沒有真正幫助我。 因此,我要用Clean語言實現的目標是將" car cow cat "
類的字符串拆分為字符串列表["car","cow","cat"]
。 您能為我提供一個詳細的答案(不一定是完整的代碼),有關如何遍歷此字符串,尤其是將新構造的字符串添加到列表中的部分嗎?
我將提供一個簡單的解決方案。 在Haskell中,有無限多種更好的方法可以做到這一點,但這是我想到的最簡單的函數式編程方法,而無需使用任何特定的Haskell函數(例如takeWhile或什至沒有折疊和貼圖)。
您基本上想模擬對列表的迭代,所以這是我的建議:
定義一個將使用字符串和分隔符的函數。 此函數將返回字符串列表spliton :: String -> Char -> [String]
要移至列表上方,我們將要吞噬字符,直到我們擊中分割字符之一。 我們還將要保存到目前為止保存的單詞以及整個單詞列表。 為此,我們將定義一個子函數來保存狀態
spliton' :: String -> Char -> String -> [String] -> [String]
spliton' [] _ sofar res = res ++ [sofar]
我還包括了最簡單的子句-空字符串。 當我們的字符串為空時,我們只想返回到目前為止保存的內容。
現在,讓我們繼續進行實際的遞歸函數:如果我們擊中分隔符,我們將到目前為止保存的字符串添加到列表中,並以空的當前狀態字符串重新開始。如果我們未擊中分隔符,我們將字符添加到當前狀態字符串
spliton' (currchar:rest) splitby sofar res | currchar==splitby = spliton' rest splitby "" (res++[sofar]) | otherwise = spliton' rest splitby (sofar++[currchar]) res
因此,總結一下我們的代碼:
spliton :: String -> Char -> [String]
spliton source splitchar = spliton' source splitchar [] []
spliton' :: String -> Char -> String -> [String] -> [String]
spliton' [] _ sofar res = res ++ [sofar]
spliton' (currchar:rest) splitby sofar res
| currchar==splitby = spliton' rest splitby "" (res++[sofar])
| otherwise = spliton' rest splitby (sofar++[currchar]) res
注意:但是,這不會擺脫空字符串-這意味着如果您有很多多余的空格-您會將它們添加到列表中。 我會讓您考慮如何處理該案件-希望這可以幫助您入門。
讓我們將其分為幾個子問題:
第一件事可以使用fromString
完成。 對於第二步和第三步,我們定義一個輔助函數:
scrape :: [Char] -> [String]
scrape [] = []
scrape cs=:[c:_]
| isSpace c = scrape (dropWhile isSpace cs)
| otherwise = [toString word:scrape rest]
where
(word,rest) = span (not o isSpace) cs
第一種選擇是匹配空列表的基本情況。 第二種選擇將整個列表cs
與第一個元素c
相匹配。 如果第一個字符是空格,則我們遞歸地(第3步)在同一列表上調用相同的函數,而沒有空格的起始部分。 如果第一個字符不是空格,則使用span :: (a -> Bool) [a] -> ([a], [a])
將列表拆分成單詞的開頭部分,其余部分。 我們使用toString
作為字符串存儲單詞,然后對列表的其余部分遞歸調用scrape
。
現在,我們只需要一個包裝即可使它成為類型為String -> [String]
的函數:
split :: String -> [String]
split s = scrape (fromString s)
where
scrape :: [Char] -> [String]
scrape [] = []
scrape cs=:[c:_]
| isSpace c = scrape (dropWhile isSpace cs)
| otherwise = [toString word:scrape rest]
where
(word,rest) = span (not o isSpace) cs
請注意,您可以通過傳遞字符d
並將isSpace c
替換為c == d
並將(not o isSpace)
為((<>) d)
來輕松地從定界符中抽象出來。 另外,您可以選擇不傳遞字符d
而是選擇函數isDelim :: Char -> Bool
。 然后,分別獲得isDelim c
和(not o isDelim)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.