过滤掉不需要的元组

时间:2014-12-18 05:36:46

标签: haskell

所以这就是我想要做的事情。我有两个(元组列表),我想拿一个列表并从其他列表中删除它的所有实例。

filly :: (Int,Int) -> [(Int,Int)] -> [(Int,Int)]
filly x = filter(\(a, b) -> a /= fst x && b /= snd x || a /= snd x && b /= fst x)

remaining :: [(Int,Int)] -> [(Int,Int)] -> [(Int,Int)]
remaining [] remain = remain
remaining h remain = remaining h2 (filly (head h) remain)
   where h2 = tail h

然而,它并不是很有效。 当我输入双重整数时,它仍会删除它们,这不是我想要的。 e.g。

remaining [(1,2)] [(1,2),(3,4),(2,2)]
returns [(1,2),(3,4)]

为什么删除(2,2)而不删除(1,2)。我希望它删除1,2和其他

我真的无法看到我出错的地方

2 个答案:

答案 0 :(得分:4)

我会做这样的事情:

filter (\tuple -> tuple `notElem` listA) listB
如果元素不存在于列表中,则返回

notElem(反引号使其成为中缀函数,如+或 - 如何工作)。因此,您只是过滤listB的内容,以便它只有listA中没有的元组。

编辑:在考虑了泽塔的评论之后,我可能误解了你的问题。为了澄清,如果您希望remaining [(1,2)] [(1,2),(2,1)]返回[],那么您还可以检查交换的元组是否也不在列表中:

import Data.Tuple

filter (\p -> p `notElem` ys && swap p `notElem` ys) xs

答案 1 :(得分:3)

  

为什么删除(2,2)而不删除(1,2)。

你的谓词错了:

(\(a, b) -> a /= fst x && b /= snd x || a /= snd x && b /= fst x)

此谓词is equivalent to

(\(a, b) -> not $ (a == fst x || b == snd x) && (a == snd x || b == fst x)

但这不是您的意思,因为这会过滤所有(a,a)(b,b),但不是 (a,b)。你的意思是

(\(a, b) -> not $ (a,b) == x || (b,a) == x)
-- or, equivalent: (\(a, b) -> (a, b) /= x && (b, a) /= x)