[英]making a takeUntil function in haskell
I want make a function which when given a string eg "ab" and "cdabd" when it will be used on these two strings it will output "cd" 我想要一个函数,当给定一个字符串,例如“ ab”和“ cdabd”时,将在这两个字符串上使用时,它将输出“ cd”
I have this up to now 我到现在为止
takeUntil :: String -> String -> String
takeUntil [] [] = []
takeUntil xs [] = []
takeUntil [] ys = []
takeUntil xs ys = if contains xs ys then -- ???? I get stuck here.
the contains function is one in which I had defined previously(this whole function should be case insensitive) contains function: 包含函数是我之前定义的(整个函数应该不区分大小写),其中包含函数:
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)
There is a lot of ways to do this, but continuing with your path, try the following: 有很多方法可以做到这一点,但是继续您的尝试,请尝试以下操作:
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)))
Some outputs: 一些输出:
takeUntil "ab" "cdabd"
"cd"
takeUntil "b" "cdabd"
"cda"
takeUntil "d" "cdabd"
"c"
takeUntil "c" "cdabd"
""
takeUntil "xxx" "cdabd"
"cdabd"
EDIT: 编辑:
The OP wants the function to be case-insensitive. OP希望该功能不区分大小写。
Well, again you can do that in lot of ways. 好了,您可以通过很多方式来做到这一点。 For example you can write a
lowerCase
function like (i think you already have it in Data.Text
): 例如,您可以编写一个
lowerCase
函数,例如(我认为您已经在Data.Text
拥有它):
import qualified Data.Char as Char
lowerCase :: String -> String
lowerCase [] = []
lowerCase (x:xs) = (Char.toLower x):(lowerCase xs)
And then use it like (maybe ugly and not very practical): 然后像这样使用它(可能很难看,但不太实用):
takeUntil (lowerCase "cd") (lowerCase "abcDe")
"ab"
That is the result you expect. 那是您期望的结果。
Also, you can use that lowerCase
function inside takeUntil
: 另外,您可以在
takeUntil
使用lowerCase
函数:
-- ...
takeUntil xs (y:ys) = if isPrefixOf (lowerCase xs) (lowerCase (y:ys))
-- ...
So, you can just do: 因此,您可以执行以下操作:
takeUntil "cd" "abcDe"
"ab"
Anyway, i think the best option is that one @bheklilr suggested. 无论如何,我认为最好的选择是建议一个@bheklilr。 Make your own
isPrefixOfCaseless
function. 制作自己的
isPrefixOfCaseless
函数。
I hope this helps. 我希望这有帮助。
Within the numerous approaches to define takeUntil
, consider using Data.Text functions as follows, 在定义
takeUntil
的众多方法中,请考虑使用Data.Text函数,如下所示,
takeUntil :: String -> String -> String
takeUntil sep txt = unpack $ fst $ breakOn (pack sep) (toCaseFold $ pack txt)
Note that pack
converts a String
to a Text
, whereas uncpak
does the inverse; 请注意,
pack
将String
转换为Text
,而uncpak
则相反。 toCaseFold
for case insensitive operations; toCaseFold
用于不区分大小写的操作; breakOn
delivers a pair where the first element includes text until the first (possible) match. breakOn
提供一对,其中第一个元素包括文本,直到第一个(可能)匹配为止。
Update 更新
This approach covers tests already suggested, yet it does not preseve original String
for instance here, 这种方法涵盖了已经建议的测试,但是在这里并没有假装原始
String
,
takeUntil "e" "abcDe"
"abcd"
A work around this involves for instance the splitting by index at the break point. 解决此问题的方法包括,例如在断点处按索引拆分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.