Joh*_*ohn 2 string haskell list filter
我是这个社区的新人.我学习Haskell并且遇到Haskell编码问题.我希望你能帮助我.
我在这里和谷歌搜索,没有任何成功.
我的问题是fowllows:我想编写一个函数,它将列表作为参数,如下所示:
myStringListFilter :: [String] -> [String]
Run Code Online (Sandbox Code Playgroud)
处理以下步骤:
删除第一个字母
myStringListFilter myList = map tail strListe myList
Run Code Online (Sandbox Code Playgroud)过滤列表中以"u"或"U"开头的每个元素.
myStringListFilter myList = filter (´elem´ ['u', 'U']) (map tail strListe myList)
Run Code Online (Sandbox Code Playgroud)第二步不起作用.我收到错误.
如果我需要以下内容,如何实现解决方案:
Input: ["butter", "chees", "aUbergine", "egg", "milk", "bUbble", "curry"]
Output: ["chees", "egg", "milk"]
Run Code Online (Sandbox Code Playgroud)
类型filter是
filter :: (a -> Bool) -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)
所以如果你想String根据谓词过滤一个s 的列表,你需要一个函数String -> Bool,但你写的(`elem` ['u',U'])是类型Char -> Bool.
所以你需要一个功能
beginsWithU :: String -> Bool
Run Code Online (Sandbox Code Playgroud)
最简单的定义方法是
beginsWithU (c:_) = c == 'u' || c == 'U'
beginsWithU _ = False -- empty list
Run Code Online (Sandbox Code Playgroud)
然后你误解了filter它是如何工作的,它保持元素满足谓词,你想要删除它们,所以你需要用一个not(或doesn'tbeginWithU直接定义)组成谓词.
但是,正如7stud 指出的那样,您实际上并不想要从原始列表中更改要保留的元素
myStringListFilter myList = filter (not . beginsWithU) (map tail myList)
Run Code Online (Sandbox Code Playgroud)
或者,无点:
myStringListFilter = filter (not . beginsWithU) . map tail
Run Code Online (Sandbox Code Playgroud)
会实现的.所以你需要将它合并tail到谓词中,并且不需要map,这会产生
myStringListFilter = filter (not . beginsWithU . tail)
Run Code Online (Sandbox Code Playgroud)
或者,如果String输入清单中出现空白的可能性应予以良好处理,
myStringListFilter = filter (not . beginsWith . drop 1)
Run Code Online (Sandbox Code Playgroud)
因为tail ""将产生*** Exception: Prelude.tail: empty list而drop 1 ""产生"".
但是,由于您希望保留原始列表元素,您还可以定义谓词以直接查看第二个字符,
secondCharIsU :: String -> Bool
secondCharIsU (_:c:_) = c == 'u' || c == 'U'
secondCharIsU _ = False
myStringListFilter = filter (not . secondCharIsU)
Run Code Online (Sandbox Code Playgroud)
建议的解决方案:
beginsWithU (c:_) = c == 'u' || c == 'U'
beginsWithU _ = False
myStringListFilter myList = filter (not . beginsWithU) (map tail myList)
ghci>myStringListFilter ["butter", "cheese", "aUbergine", "egg", "milk", "bUbble", "curry"]
["heese","gg","ilk"]
Run Code Online (Sandbox Code Playgroud)
...不会产生正确的输出。
映射会更改原始字符串,因此过滤映射字符串的列表将不会生成包含任何原始字符串的列表。该操作需要使用自定义过滤器来过滤原始列表:
myFilter :: String -> String -> Bool
myFilter notAllowedChars str =
if head (tail str) `elem` notAllowedChars
then False --if match, reject this string
else True --if no match, include this string in result list
ghci>filter (myFilter "uU") ["butter", "cheese", "aUbergine", "egg", "milk", "bUbble", "curry"]
["cheese","egg","milk"]
Run Code Online (Sandbox Code Playgroud)
无点:
filterBy :: String -> String -> Bool
filterBy notAllowedChars =
not . (`elem` notAllowedChars) . head . tail
Run Code Online (Sandbox Code Playgroud)
请记住,字符数组(例如 ['u', 'U'])与字符串“uU”相同。