如何通过 Haskell 中的自引用键删除列表的一部分

How to remove portions of a list by self referencing keys in Haskell

我有一个这种类型的列表:[(a, [a])]。 例如:

[("a",["x","y"]),("x",["a","y"]),("z",[]),("y",["a","x"])]

我想过滤这个列表。过滤应该像这样工作:

  1. 从第一个项目开始,从第一个元组遍历项目
  2. 删除第一个元组中的键(因此删除 "x""y"

最终结果应该变成:

[("a",["x","y"]),("z",[])] -- the "x" and "y" are removed because they live in "a"

我们的想法是获取一个列表,然后在该列表上应用 import qualified Data.Map as Map 中的 Map.delete。但是,当 Maybe 被引入时,我被困在了事情上。这是我的代码:

import System.IO
import Data.Maybe as Maybe
import qualified Data.Map as Map


list = [("a",["x","y"]),("x",["a","y"]),("z",[]),("y",["a","x"])]
    
main :: IO ()
main = do
    let myMap = Map.fromList list
    let myList = funcA list myMap 
    print myList
    
funcA (x:xs) myMap
   | f == Nothing = Nothing
--   | otherwise = f
--   | otherwise = funcC f myMap
   | otherwise = Maybe.maybeToList f
    where a = fst x
          f = funcB a myMap

funcB key myMap = Map.lookup key myMap

funcC portion myMap = portion

你能帮帮我吗?

----------------编辑

回答代码后将如下所示:

import System.IO
import Data.Maybe as Maybe
import qualified Data.Map as Map


list = [("a",["x","y"]),("x",["a","y"]),("z",[]),("y",["a","x"])]
    
main :: IO ()
main = do
    let myList = removeKeys list
    print myList


removeKeys :: Eq a => [(a, [a])] -> [(a, [a])]
removeKeys [] = []
removeKeys (kv@(_, vs): kvs) = kv : removeKeys (filter ((`notElem` vs). fst) kvs)

输出:

> runghc program
[("a",["x","y"]),("z",[])]

我喜欢回答的解决方案,因为使用了创造性的方式 filter。它基本上是这样做的:

Prelude> let vs = ["x","y"]
Prelude> let kvs = [("x",["a","y"]),("z",[]),("y",["a","x"])]
Prelude> filter ((`notElem` vs). fst) kvs
[("z",[])]

您可以创建一个递归函数,用二元组的第二项中的项过滤列表的其余部分,因此:

removeKeys :: Eq a => [(a, [a])] -> [(a, [a])]
removeKeys [] = []
removeKeys (kv@(_, vs): kvs) = kv : removeKeys (filter (<strong>(`notElem` vs). fst</strong>) kvs)

key-value 对已删除项目中的值中的项目将不予考虑。因此,如果 "x" 例如有 ("x", ["a", "y", "z"]),它不会删除 "z",因为它在一个已经被删除的项目中。