我觉得这应该是相当明显或容易的,但我无法得到它。我想要做的是将一个函数应用于列表(使用map),但仅在条件被保持时。想象一下,你只想划分偶数的数字:
map (`div` 2) (even) [1,2,3,4]
这将给出[1,1,3,2],因为只有偶数才能将函数应用于它们。显然这不起作用,但有没有办法让这项工作无需编写你可以给地图分离的单独功能?过滤器几乎就在那里,除了我还想保留条件不适用的元素,而不是将函数应用于它们。
由于
答案 0 :(得分:10)
如果您不想定义单独的函数,请使用lambda。
map (\x -> if (even x) then (x `div` 2) else x) [1,2,3,4]
或者代替地图,列表理解,我认为更具可读性。
[if (even x) then (x `div` 2) else x | x <- [1,2,3,4]]
答案 1 :(得分:7)
mapIf p f = map (\x -> if p x then f x else x)
答案 2 :(得分:3)
除了PiotrLegnica的答案之外:通常,如果你声明一个辅助函数而不是使用lambda,它会更容易阅读。考虑一下:
map helper [1..4] where
helper x | even x = x `div` 2
| otherwise = x
([1..4]
是[1,2,3,4]
)的糖
如果您想要删除所有其他元素,请考虑使用filter
。 filter
删除所有不满足谓词的元素:
filter even [1..4] -> [2,4]
因此,您可以构建map
的管道并过滤或使用列表理解:
map (`div` 2) $ filter even [1..4]
[x `div` 2 | x <- [1..4], even x]
选择你最喜欢的任何东西。
答案 3 :(得分:2)
制作自己的帮助函数制作者:
ifP pred f x =
if pred x then f x
else x
custom_f = ifP even f
map custom_f [..]
(警告:我现在无法访问编译器。我猜这可以正常工作......)
答案 4 :(得分:1)
我喜欢其他更通用的解决方案,但在您非常特殊的情况下,您可以使用
map (\x -> x `div` (2 - x `mod` 2)) [1..4]
答案 5 :(得分:0)
主要是取消现有的答案,但根据我对“可读”的偏见定义(我喜欢警卫而不是ifs,where
超过let
):
mapIf p f = map f'
where f' x | p x = f x | otherwise = x
ghci说它可能有效
ghci> let mapIf p f = map f' where f' x | p x = f x | otherwise = x
ghci> mapIf even (+1) [1..10]
[1,3,3,5,5,7,7,9,9,11]