简体   繁体   English

从 Haskell 中的字符串列表中删除字符串

[英]Removing a string from a list of strings in Haskell

I have a question regarding Haskell that's been stumping my brain.我有一个关于 Haskell 的问题一直困扰着我。 I'm currently required to write a function that removes a string ie "word" from a list of strings ["hi", "today", "word", "Word", "WORD"] returns the list ["hi", "today", "Word", "WORD"] .我目前需要编写一个函数来从字符串列表中删除一个字符串,即"word" ["hi", "today", "word", "Word", "WORD"]返回列表["hi", "today", "Word", "WORD"] I cannot use any higher-order functions and can only resort to primitive recursion.我不能使用任何高阶函数,只能求助于原始递归。

Thinking about the problem, I thought maybe I could solve it by using a recursion where you search the head of the first string, if it matches "w" then compare the next head from the tail, and see if that matches "o" .考虑这个问题,我想也许我可以通过使用递归来解决它,你搜索第一个字符串的头部,如果它匹配"w"然后比较尾部的下一个头部,看看是否匹配"o" But then I soon realized that after all that work, you wouldn't be able to delete the complete string "word" .但后来我很快意识到,完成所有这些工作后,您将无法删除完整的字符串"word"

My question really being how do I compare a whole string in a list rather than only comparing 1 element at a time with something like: removeWord (x:xs) .我的问题实际上是如何比较列表中的整个字符串,而不是一次只比较 1 个元素,例如: removeWord (x:xs) Is it even possible?甚至有可能吗? Do I have to write a helper function to aid in the solution?我是否必须编写一个辅助函数来帮助解决?

Consider the base case: removing a word from an empty list will be the empty list.考虑基本情况:从空列表中删除一个单词将是空列表。 This can be trivially written like so:这可以简单地写成这样:

removeWord [] _ = []

Now consider the case where the list is not empty.现在考虑列表不为空的情况。 You match this with x:xs .其与x:xs 匹配 You can use a guard to select between these two conditions:您可以使用 守卫在这两个条件之间进行选择:

  1. x is the word you want to remove. x是您要删除的单词。 ( x == word ) ( x == word )
  2. x is not the word you want to remove. x不是您要删除的单词。 ( otherwise ) otherwise

You don't need a helper function, though you could write one if you wanted to.您不需要辅助函数,但如果您愿意,也可以编写一个。 You've basically got 3 conditions:你基本上有3个条件:

  1. You get an empty list.你得到一个空列表。
  2. You get a list whose first element is the one you want to remove.您会得到一个列表,其第一个元素是您要删除的元素。
  3. You get a list whose first element is anything else.你会得到一个列表,它的第一个元素是其他任何元素。

In other languages, you would do this with a set of if-else statements, or with a case statement, or a cond .在其他语言中,您可以使用一组 if-else 语句、 case语句或cond In Haskell, you can do this with guards:在 Haskell 中,你可以用守卫来做到这一点:

remove_word_recursive:: String -> [String] -> [String]
remove_word_recursive _ []                              = []
remove_word_recursive test_word (x:xs) | test_word == x = what in this case?
remove_word_recursive test_word (x:xs)                  = what in default case?

Fill in the correct result for this function in these two conditions, and you should be done.在这两种情况下为这个函数填写正确的结果,你应该就完成了。

I think what you're looking for is a special case of the function sought for this question on string filters: Haskell - filter string list based on some conditions .我认为你正在寻找的是在字符串过滤器上为这个问题寻求的函数的一个特例: Haskell-filter string list based on some conditions Reading some of the discussion on the accepted answer might help you understand more of Haskell.阅读有关已接受答案的一些讨论可能会帮助您更多地了解 Haskell。

Since you want to remove a list element, it's easy to do it with List Comprehension.由于您要删除列表元素,因此使用 List Comprehension 很容易做到。

myList = ["hi", "today", "word", "Word", "WORD"]
[x | x <- myList, x /= "word"]

The result is:结果是:

["hi","today","Word","WORD"]

If isInfixOf is not considered as higher order, then如果isInfixOf不被视为高阶,则

import Data.List (isInfixOf)
filter  (not . isInfixOf "word")  ["hi", "today", "word", "Word", "WORD"]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM