假设我有两个列表,其中一个是布尔值:
[True, False, True]
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
是否有一个函数来逐个索引地比较这些列表,并创建一个新的"真"值列表?
[1, 3]
Run Code Online (Sandbox Code Playgroud)
此外,列表理解可以在这里非常有效地使用:
[ghci] let a = [True, False, True]
[ghci] let b = [1,2,3]
[ghci] [ b1 | (a1, b1) <- zip a b, a1]
[1,3]
[ghci]
Run Code Online (Sandbox Code Playgroud)
这样可以解决问题:
fliterAccordingTo :: [Bool] -> [a] -> [a]
filterAccordingTo bs xs = map snd . filter fst $ zip bs xs
Run Code Online (Sandbox Code Playgroud)
zip将布尔值与值filter fst配对,仅选择具有True第一个元素的对,并map snd生成仅包含对的第二个元素的列表(即值).
不是默认情况下,但创建一个非常简单,
zip获取两个列表并创建一个新列表,每个元素配对在一起.我们可以使用filter删除不满足谓词的项,然后map将函数应用于列表的所有元素.
transform :: [Bool] -> [a] -> [a]
transform xs = map ???2 . filter ???1 . zip xs
Run Code Online (Sandbox Code Playgroud)
由于这是看起来有点像功课,我让你在填写???的
???1如果该对的第一个元素为true,则???2应该返回true,并且应该返回第二个元素.
这是最简单的解决方案,我们可以预期编译器应融合map并filter进入单个列表遍历.