繁体   English   中英

从列表元组列表中过滤元组

[英]Filter Tuples from List of List Tuples

我有一个嵌套在两个列表中的元组,我试图根据它们是否一致来过滤这些元组。

我需要检查元组的第一个元素,并且任何匹配的元素都应该具有相同的 Bool。 否则它应该从列表中删除。 我的输入看起来像这样。

[[('a',True),('a',False),('b',True),('c',False),('a',False)], [('a',True),('a',True),('b',True),('b',False)]]

我正在努力实现:

[[('b',True),('c',False),], [('a',True),('a',True)]]

'a' 从第一个列表中删除,因为 True 和 False 都与 'a' 相关联,然后 'b' 从第二个列表中删除,因为 True 和 False 都与 'b' 相关联。

我认为通过将任务分解为单独的功能,它会更容易。 所以我创建了这个 mapTuples 函数来创建一个具有相同第一个元素的元组列表。

mapTuples :: [(Char,Bool)] -> [(Char,Bool)]
mapTuples (x:y:ys) | fst(x) == fst(y) = ((y):mapTuples (x:ys))
                   | otherwise = mapTuples (x:ys)
mapTuples (x:[]) = [x]
mapTuples [] = []

从这里我制作了一个 function checkTuples,以检查上述 function 中的列表,看看是否有任何布尔值不匹配。 如果它们都匹配,它将返回 True,否则返回 False。

checkTuples :: [(Char,Bool)] -> Bool
checkTuples (x:y:ys) | snd(x) /= snd(y) = False
                     | otherwise = checkTuples(x:ys)
checkTuples (x:[]) = True

最后我有我的 removeConflicts 来删除任何不一致的元组。 我用它来循环我的列表和元组。

removeConflicts :: [[(Char,Bool)]] -> [[(Char,Bool)]]
removeConflicts (x:ys) | checkTuples(mapTuples(x)) == False = removeConflicts(ys)
                       | otherwise = x:removeConflicts(ys)
removeConflicts [] = []

目前无法按预期工作,我知道这是因为这部分:

False = removeConflicts(ys)

我相信我还需要以某种方式包括已过滤的 x 值。 但我不确定如何 go 这样做。 就像是

removeConflicts (x:ys) | checkTuples(mapTuples(x)) == False = removeConflicts(filtered(x):ys)

在哪里过滤(x)删除不需要的元组。

希望这一切都有意义,并对冗长的解释感到抱歉,不想遗漏任何内容。

我的第一句话是,您通过谈论元组列表的列表使本规范变得复杂。 您描述的计算是以相同的方式转换此嵌套列表中的每个列表:这就是map所做的。 所以我们可以将问题减少到

removeConflicts :: [[(Char, Bool)]] -> [[(Char, Bool)]]
removeConflicts = map processList

对于某些processList:: [(Char, Bool)] -> [(Char, Bool)]我们必须定义。 让我们开始吧。

processList :: [(Char, Bool)] -> [(Char, Bool)]
processList [] = []
processList ((label, value):more) = _

很容易处理一个空列表。 对于非空列表,我们希望将列表分成两部分:与此共享相同 label 的元组和不共享的元组。 一些 Hoogling 会发现partition适合这个任务,所以:

processList :: [(Char, Bool)] -> [(Char, Bool)]
processList [] = []
processList xs@((label, value):_) =
  let (same, different) = partition ((== label) . fst) xs
  in _

现在我们有了这两部分的列表,剩下要做的就是 (1) 决定是保留same的块还是丢弃它,以及 (2) 在different上递归调用我们自己:

processList :: [(Char, Bool)] -> [(Char, Bool)]
processList [] = []
processList xs@(x@(label, value):_) =
  let (same, different) = partition ((== label) . fst) xs
      chunk | all (== x) same = same
            | otherwise = []
  in chunk ++ processList different

最后,让我们通过将这些过度特定的类型泛化为Eq类型的多态来进行清理:

removeConflicts :: (Eq a, Eq b) => [[(a, b)]] -> [[(a, b)]]
removeConflicts = map processList

processList :: (Eq a, Eq b) => [(a, b)] -> [(a, b)]
processList [] = []
processList xs@(x@(label, value):_) =
  let (same, different) = partition ((== label) . fst) xs
      chunk | all (== x) same = same
            | otherwise = []
  in chunk ++ processList different

暂无
暂无

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

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