【问题标题】:Filter a list of strings using a pair of strings使用一对字符串过滤字符串列表
【发布时间】:2012-10-09 03:48:20
【问题描述】:

我想定义一个 Haskell 函数,它从字符串列表中删除一对字符串中包含的任何字符串,并仅返回一个包含所有剩余字符串的列表。所以一个例子是:

function ["football","basketball","soccer"] ("football", "basketball") = ["soccer"]

我知道您可以使用filter 函数来过滤满足给定谓词的列表。我知道我可以通过这种方式过滤掉一个列表:

function' xs s = filter (/=s) xs

但我不知道如何让它与元组一起工作。当我运行代码时,我不断收到错误。知道怎么做吗?谢谢

【问题讨论】:

    标签: string list haskell functional-programming tuples


    【解决方案1】:

    更通用的解决方案是使用一个字符串列表来过滤,而不仅仅是一对。更通用的解决方案是使用支持 Eq 的任何内容的列表,而不仅仅是字符串。

    所以,我们正在寻找具有以下类型的东西:

    Eq a => [a] -> [a] -> [a]
    

    快速搜索 hoogle 得到(\\)

    import Data.List ((\\))
    
    main = print $ ["football","basketball","soccer"] \\ ["football", "basketball"]
    

    【讨论】:

      【解决方案2】:
      myfunc :: Eq a => [a] -> (a, a) -> [a]
      myfunc xs (a,b) = filter (\x -> (x /= a) && (x /= b)) xs
      

      让我们看看filter的类型

      filter :: (a -> Bool) -> [a] -> [a]
      

      当你做filter f xs时, 它只是将a -> Bool 类型的函数f 应用于列表的所有元素,删除该函数返回False 的元素。

      我将元组元素的模式匹配为(a,b),我刚刚将函数f 定义为\x -> (x /= a) && (x /= b)。这是一个匿名函数,它接受列表中的一个元素并仅在它既不等于元组的第一个元素也不等于第二个元素时返回True&& 是布尔值 and,因此只有当它的两个参数都是 True 时它才会返回 True

      【讨论】:

      • 您能否进一步解释一下。我想确保我正确理解了这一点。谢谢
      • @Bobo 我已经添加了解释。
      【解决方案3】:

      最直接的方法是运行过滤器两次,就像这样。

      tupleFilter :: (Eq a) => [a] -> (a, a) -> [a]
      tupleFilter xs (a, b) = function' (function' xs a) b
      

      这里的关键是,在使用过滤器中的元素之前,对元组进行模式匹配(或解构)。

      这是一个没有中间过滤器功能的版本,在这种情况下可能应该内联以供将来阅读。

      tupleFilter xs (a, b) = filter (\x -> (x /= a) && (x /= b)) xs
      

      【讨论】:

        猜你喜欢
        • 2017-05-10
        • 2022-01-16
        • 1970-01-01
        • 2019-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        相关资源
        最近更新 更多