[英]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.