[英]making a takeUntil function in haskell
我想要一个函数,当给定一个字符串,例如“ ab”和“ cdabd”时,将在这两个字符串上使用时,它将输出“ cd”
我到现在为止
takeUntil :: String -> String -> String
takeUntil [] [] = []
takeUntil xs [] = []
takeUntil [] ys = []
takeUntil xs ys = if contains xs ys then -- ???? I get stuck here.
包含函数是我之前定义的(整个函数应该不区分大小写),其中包含函数:
contains :: String -> String -> Bool
contains _ [] = True
contains [] _ = False
contains xs ys = isPrefixOf (map toLower ys) (map toLower xs) || contains (tail(map toLower xs) (map toLower ys)
有很多方法可以做到这一点,但是继续您的尝试,请尝试以下操作:
import Data.List
takeUntil :: String -> String -> String
takeUntil [] [] = [] --don't need this
takeUntil xs [] = []
takeUntil [] ys = []
takeUntil xs (y:ys) = if isPrefixOf xs (y:ys)
then []
else y:(takeUntil xs (tail (y:ys)))
一些输出:
takeUntil "ab" "cdabd"
"cd"
takeUntil "b" "cdabd"
"cda"
takeUntil "d" "cdabd"
"c"
takeUntil "c" "cdabd"
""
takeUntil "xxx" "cdabd"
"cdabd"
编辑:
OP希望该功能不区分大小写。
好了,您可以通过很多方式来做到这一点。 例如,您可以编写一个lowerCase
函数,例如(我认为您已经在Data.Text
拥有它):
import qualified Data.Char as Char
lowerCase :: String -> String
lowerCase [] = []
lowerCase (x:xs) = (Char.toLower x):(lowerCase xs)
然后像这样使用它(可能很难看,但不太实用):
takeUntil (lowerCase "cd") (lowerCase "abcDe")
"ab"
那是您期望的结果。
另外,您可以在takeUntil
使用lowerCase
函数:
-- ...
takeUntil xs (y:ys) = if isPrefixOf (lowerCase xs) (lowerCase (y:ys))
-- ...
因此,您可以执行以下操作:
takeUntil "cd" "abcDe"
"ab"
无论如何,我认为最好的选择是建议一个@bheklilr。 制作自己的isPrefixOfCaseless
函数。
我希望这有帮助。
在定义takeUntil
的众多方法中,请考虑使用Data.Text函数,如下所示,
takeUntil :: String -> String -> String
takeUntil sep txt = unpack $ fst $ breakOn (pack sep) (toCaseFold $ pack txt)
请注意, pack
将String
转换为Text
,而uncpak
则相反。 toCaseFold
用于不区分大小写的操作; breakOn
提供一对,其中第一个元素包括文本,直到第一个(可能)匹配为止。
更新
这种方法涵盖了已经建议的测试,但是在这里并没有假装原始String
,
takeUntil "e" "abcDe"
"abcd"
解决此问题的方法包括,例如在断点处按索引拆分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.