我必须编写一个函数,给定一个键列表找到所有值 与给定关联列表中的这些键相关联,其中键可以具有多于一个的关联值。因此,该函数必须连接各个键的查找结果。
以下是lookupOne
的代码:
lookupOne :: Int -> [(Int,a)] -> [a]
lookupOne x list = [values | (key,values)<-list, x==key]
现在我必须编写lookupAll
的代码,该代码将查找列表中的每个键并将其与该对匹配,然后附加结果。我必须遵循这个:
lookupAll :: [Int] -> [(Int,a)] -> [a]
lookupAll ... =
所以我尝试了很多方法来做到这一点,但我无法解决这个问题:如何提取密钥的一个元素(因为我的lookupOne
只需要Int
而不是{{1}每次都查看[Int]
对。我尝试使用map函数,但它不起作用,因为我不知道如何映射使用两个参数((key,value)
)的函数,因为map显然只需要一个列表作为参数。我也无法弄清楚如何模式匹配它,因为显然lookupOne
并不意味着在下一轮它将再次只提取xs
的一个元素你能不能帮我理解这个&lt; 3
答案 0 :(得分:3)
可能有更简洁有效的方法来执行此操作,但坚持原始实现,您可以这样写:
lookupAll :: [Int] -> [(Int,a)] -> [a]
lookupAll xs list = [values | (key,values) <- list, key `elem` xs]
答案 1 :(得分:0)
你想使用map
,没关系。现在你已经意识到你需要一个只接受一个参数的函数,即密钥,但是looupOne
需要两个。但是,list
参数对于每次调用都是相同的,因此我们可以执行以下操作。
lookupAll :: [Int] -> [(Int,a)] -> [a]
lookupAll xs list = ...
where f x = lookupOne x list
f
是你需要的那种功能。现在我们可以map f xs
,但结果将是一个列表列表。您可以对结果使用concat
,也可以查看concatMap
的定义,了解如何使用该结果。
如果您喜欢列表推导,那么您也可以尝试
lookupAll xs list = [... | x <- xs, ... <- lookupOne x list, ... <- ...]
我留给你(因为它看起来像家庭作业)来弄清楚其余部分。