【问题标题】:Remove characters from a string in all elements of a list从列表的所有元素中的字符串中删除字符
【发布时间】:2019-04-21 00:46:07
【问题描述】:

我试图在列表中替换所有本身包含子字符串的字符串。 我已经尝试过使用map 函数:

cleanUpChars = map(\w -> if isInfixOf "**" w then map(\c ->  if c == "*" then ""; else c); else w)

对我来说,这读作:映射列表中的元素,这样如果单词的字符包含 * 则用任何内容替换它

致 Haskell:“无法将预期类型 [[Char]] -> [[Char]] 与表达式中的实际类型 [Char] 匹配:w”(最后的 w 带有下划线)

感谢任何帮助

【问题讨论】:

  • 你是import Data.List 的函数吗? hoogle.haskell.org/?hoogle=isInfixOf
  • 太累了!谢谢。不过,我的逻辑似乎仍然是错误的,所以编辑了
  • 你不需要分号。

标签: list dictionary haskell


【解决方案1】:

回答修改后的问题(当isInfixOf 已正确imported 时):

cleanUpChars = map(\w -> if isInfixOf "**" w then map(\c ->  if c == "*" then ""; else c); else w)

这里最明显的错误是内括号中的c 将是Char(因为它是mapped 超过String 的函数的输入)-并且字符使用单引号,而不是双引号。但是,这不仅仅是拼写错误或语法错误的情况 - "" 可以作为空字符串正常工作(并且等效于 [],因为字符串只是列表),但不存在“空字符”。

如果看起来您的目标是从包含** 的列表中的每个字符串中删除所有*s,那么正确的工具是filter 而不是map

Prelude Data.List> cleanUpChars = map(\w -> if isInfixOf "**" w then filter (/= '*') w; else w)
Prelude Data.List> cleanUpChars ["th**is", "is", "a*", "t**es*t"]
["this","is","a*","test"]

(请注意,在我编写的示例中,它删除了 t**es*t 中的所有星号,甚至是单个星号。这可能不是您真正想要的,但这是您在错误版本中所暗示的逻辑 - 您将必须稍微复杂一点才能仅删除连续的* 对。)

PS 我绝对不会用分号写出这样的函数——它真的不会给你带来任何好处。我还会使用isInfixOf 的中缀形式,这样可以更清楚您在另一个字符串中查找的字符串:

cleanUpChars :: [String] -> [String]
cleanUpChars = map (\w -> if "**" `isInfixOf` w then filter (/= '*') w else w)

我对它的可读性仍然不是特别满意 - 可能有一些我现在忽略的好方法来整理它。但即使不是,它也有助于 imo 为函数提供本地名称(希望你能想出一个比我的版本更简洁的名称!):

cleanUpChars :: [String] -> [String]
cleanUpChars = map possiblyRemoveAsterisks
    where possiblyRemoveAsterisks w = if "**" `isInfixOf` w then filter (/= '*') w else w

【讨论】:

  • 内容丰富且很好的答案,谢谢!快速哪个,isInfixOf 周围的 ` 是什么意思/做什么?
  • 反引号只允许您以“中缀形式”使用它——在两个参数之间,而不是在它们之前。您可以使用 2 个参数的任何函数来执行此操作,但在某些情况下,它以中缀形式读起来要好得多,在我看来 isInfixOf 和朋友显然属于该类别
猜你喜欢
  • 2022-07-06
  • 1970-01-01
  • 2020-04-05
  • 1970-01-01
  • 2022-07-05
  • 2017-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多