簡體   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