对于字符串str
,如何在n
出现c
字符后删除每个字符?
例如,如果str
为"2016-10-20"
,那么如何在第二次出现字符-
后删除每个字符,产生"2016-10"
?
答案 0 :(得分:3)
标准库中没有方便的split
功能,因此您必须自己滚动。一种方法:
dropAfter :: Int -> Char -> String -> String
dropAfter _ _ "" = ""
dropAfter 0 d (x:xs) = ""
dropAfter 1 d (x:xs) | x == d = ""
dropAfter n d (x:xs) | x == d = x : dropAfter (n-1) d xs
| otherwise = x : dropAfter n d xs
split
包确实提供了splitOn :: Eq a => [a] -> [a] -> [[a]]
:
import Data.List.Split (splitOn)
import Data.List (intercalate)
dropAfter n d = intercalate [d] . take n . splitOn [d]
答案 1 :(得分:3)
折叠的恶魔再次袭来。
dropAfter :: Int -> (a -> Bool) -> [a] -> [a]
dropAfter n _ _ | n < 1 = []
dropAfter n f xs = foldr go (`seq` []) xs n where
go x r !k
| f x = if k == 1 then [] else x : r (k - 1)
| otherwise = x : r k
答案 2 :(得分:1)
或者,您可以使用它作为开始使用解析器的垫脚:
λ import Text.Parsec
λ runParser (many (noneOf "-") `sepBy` char '-') () "example from question" "2016-01-43"
Right ["2016","01","43"]
λ import Data.List
λ intercalate "-" . take 2 <$> it
Right "2016-01"
现在进行切换的好处在于,随着您对输入的更多了解(以及它能够和不可能看起来如何),更新解析器以进行匹配相当容易,使用自定义函数可以真正快速变得真实。