检查列表是否在元组列表中

时间:2017-02-14 01:28:32

标签: haskell

我正在尝试编写一个函数,我必须将元组与元组列表进行匹配,如果我的第一个元组的两个元素出现在后面列表的任何元组中,则返回一个bool。到目前为止,我尝试使用elem(仅当我的第一个列表与子列表具有相同数量的元素时才有效)和isInfixOf(变量不在范围内)。有任何提示吗?

matching ("Monday","Tuesday") [("Monday","Tuesday",10),("Tuesday","Sunday",20), ("Wednesday", "Friday", 22)] -> False
matching ("Monday","Tuesday") [("Tuesday","Monday",10),("Tuesday","Sunday",20), ("Wednesday", "Friday", 22)] -> False

3 个答案:

答案 0 :(得分:3)

让我们看看你想做什么:

  1. 您必须将元组与另一个长度的元组匹配,如果匹配则返回True,否则返回False
  2. 将此项应用到我们的列表中,如果有匹配则返回True,如果没有,则返回False
  3. 是否有任何标准功能有帮助? Hoogle是用于尝试查找有用功能的资源。当然,在知道要搜索的内容方面存在学习曲线。

    我尝试(a -> b -> Bool) -> a -> [b] -> Bool这是您的函数类型,其中a是您要匹配的元组,b是列表中的元组。这没有得到任何有用的匹配。但后来我尝试(b -> Bool) -> [b] -> Bool结果为here,第二个匹配是一个名为any的函数(第一个函数是all,它很有用,但不会对你做什么想!)。

    现在我们需要的是一个接收元组的函数,如果它们匹配则返回true。

    使用你的元组我试过(a,b) -> (a,b,c) -> Bool并且......发现没有匹配!看起来我们将不得不自己写。

    这样的事情应该有效: compareTuples a b = fst a == fst b && snd a == snd bcompareTuples (a,b) (c,d, _) = a == c && b == d

    嗯,这个函数的类型为(a -> b -> Bool),但any需要(b -> Bool),那么我们如何才能完成这项工作呢?通过部分应用当然!

    matching t xs = any (compareTuples t) xs

答案 1 :(得分:1)

这是使用折叠的一种方式:

matching (p,q) lst = foldl (\acc (x,y,_) -> if (x == p) && (y==q) then True || acc else False || acc) False lst

基本上,对列表中的元组进行输入模式匹配。如果找到至少一个匹配,则累加器将设置为True。

答案 2 :(得分:1)

如果您使用lenses

,这很简单
globalVariable undefined

使用eta减少可以进一步简化:

matching a bs = not . any (\b -> (a^._1 == b^._1 && a^._2 == b^._2)
                              || (a^._1 == b^._2 && a^._2 == b^._1) ) $ bs