Joh*_*ohn 2 haskell list map filter toupper
我有一个列表[String]任务是删除列表中的那些元素,它们有"q"或"p",然后用toUpper大写列表中的所有字母.
我尝试的是如下:
delAndUpper :: [String] -> [String]
delAndUpper myList = filter (\x -> not('p' `elem` x || 'q' `elem` x)) myList
Run Code Online (Sandbox Code Playgroud)
它正确地从列表中删除了不需要的元素,但由于toUpper的类型是Char,因此无法在此列表中应用toUpper.
我用地图试了一下它不起作用.
delAndUpper myList = map toUpper (filter (\x -> not('p' `elem` x || 'q' `elem` x)) myList)
Run Code Online (Sandbox Code Playgroud)
我知道,在这行代码中,toUpper获取一个列表作为值,因此它无法工作,但知道如何进入列表并将应用映射到上层.
请你帮助我好吗.
提前致谢!
问候
你需要使用map (map toUpper).
这是因为你有[String]而不是String.
toUpper :: Char -> Char
map toUpper :: [Char] -> [Char]
Run Code Online (Sandbox Code Playgroud)
即
map toUpper :: String -> String
map (map toUpper) :: [String] -> [String]
Run Code Online (Sandbox Code Playgroud)
map toUpper通过使每个字母为大写来大写map (map toUpper)字符串,因此大写字符串列表中的每个字符串.
你的功能变了
delAndUpper myList = map (map toUpper) (filter (\x -> not('p' `elem` x || 'q' `elem` x)) myList)
Run Code Online (Sandbox Code Playgroud)
dave4420提出了一个很好的建议,这(map.map) toUpper是一种简洁的写作方式map (map toUpper),可以帮助你简单而自然地思考两个列表级别 - 看看他的答案.
你问是否有更短的方法来编写条件,并且不喜欢硬编码`q`和`p`.我同意那些多位`elem`不漂亮.让我们在不允许的字母列表中传递并整理一下:
delAndUpper omit strings = map (map toUpper) (filter ok strings) where
ok xs = not (any (`elem` omit) xs)
Run Code Online (Sandbox Code Playgroud)
这里(`elem` omit)检查一个字符是否在导致我们省略该字的列表中,因此(any (`elem` omit) xs)检查是否xs禁止任何字符.当然,如果没有人被禁止,那就是ok.
您原来delAndUpper现在是delAndUpper "pq",或者如果你还希望禁止资本P和Q delAndUpper "pqPQ".(稍后会详细介绍.)
让我们看看我们是否能写得ok更短.我的第一个想法就是使用pointfree它(请参阅我对另一个问题的回答,了解如何让它在ghci中运行),但它似乎挂了,所以使用一些标准的转换技巧,我们可以not用一个带有两个参数的函数组合在给我们一个Bool之前,(not.).f而不是not.f像我们在第一次输入后给我们一个Bool的函数一样.any正在把(`elem` omit)它作为第一个论点.这给了我们
ok xs = ((not.).any) (`elem` omit) xs
Run Code Online (Sandbox Code Playgroud)
从中我们可以删除尾随的xs:
ok = ((not.).any) (`elem` omit)
Run Code Online (Sandbox Code Playgroud)
和内联:
delAndUpper omit strings = map (map toUpper) (filter (((not.).any) (`elem` omit)) strings)
Run Code Online (Sandbox Code Playgroud)
我也不热衷于落后strings:
delAndUpper omit = map (map toUpper).filter (((not.).any) (`elem` omit))
Run Code Online (Sandbox Code Playgroud)
(我们也可以摆脱这个omit争论并完全免费获得,但在我难以理解的道路上,这将会走得太远了.)
> delAndUpper "pq" $ words "The Queen has probably never had a parking ticket."
["THE","QUEEN","HAS","NEVER","HAD","A","TICKET."]
Run Code Online (Sandbox Code Playgroud)
这是必需的行为吗?仔细排除小写变体然后将所有内容都设为大写似乎很奇怪.我们可以反过来这样做:
upperAndDel omit = filter (((not.).any) (`elem` omit)).map (map toUpper)
Run Code Online (Sandbox Code Playgroud)
给
> upperAndDel "PQ" $ words "The Queen has probably never had a parking ticket."
["THE","HAS","NEVER","HAD","A","TICKET."]
Run Code Online (Sandbox Code Playgroud)