如果谓词成立则映射函数

发布于 2024-10-17 01:31:19 字数 303 浏览 3 评论 0原文

我觉得这应该是相当明显或容易的,但我就是不明白。我想要做的是将函数应用于列表(使用 map),但前提是满足条件。想象一下,您只想除偶数:

map (`div` 2) (even) [1,2,3,4]

这会给出 [1,1,3,2] ,因为只有偶数才会应用该函数。显然这是行不通的,但是有没有一种方法可以让这个工作不需要编写一个可以提供给 map 的单独函数? filter 几乎就在那里,除了我还想保留条件不成立的元素,并且只是不将函数应用于它们。

I feel like this should be fairly obvious, or easy, but I just can't get it. What I want to do is apply a function to a list (using map) but only if a condition is held. Imagine you only wanted to divide the numbers which were even:

map (`div` 2) (even) [1,2,3,4]

And that would give out [1,1,3,2] since only the even numbers would have the function applied to them. Obviously this doesn't work, but is there a way to make this work without having to write a separate function that you can give to map? filter is almost there, except I also want to keep the elements which the condition doesn't hold for, and just not apply the function to them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

-黛色若梦 2024-10-24 01:31:19

如果您不想定义单独的函数,请使用 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]]

If you don't want to define separate function, then use lambda.

map (\x -> if (even x) then (x `div` 2) else x) [1,2,3,4]

Or instead of a map, list comprehension, bit more readable I think.

[if (even x) then (x `div` 2) else x | x <- [1,2,3,4]]
半暖夏伤 2024-10-24 01:31:19
mapIf p f = map (\x -> if p x then f x else x)
mapIf p f = map (\x -> if p x then f x else x)
荒路情人 2024-10-24 01:31:19

除了 PiotrLegnica 的答案:通常,如果声明一个辅助函数而不是使用 lambda,则更容易阅读。考虑一下:(

map helper [1..4] where
  helper x | even x    = x `div` 2
           | otherwise = x

[1..4][1,2,3,4] 的糖)

如果您想删除所有其他元素,请考虑使用过滤器。 filter 删除所有不满足谓词的元素:

filter even [1..4] -> [2,4]

因此您可以构建一个 map 管道并过滤或使用列表理解:

map (`div` 2) $ filter even [1..4]
[x `div` 2 | x <- [1..4], even x]

选择您最喜欢的任何内容。

In addition to the answer of PiotrLegnica: Often, it's easier to read if you declare a helper function instead of using a lambda. Consider this:

map helper [1..4] where
  helper x | even x    = x `div` 2
           | otherwise = x

([1..4] is sugar for [1,2,3,4])

If you want to remove all the other elements instead, consider using filter. filter removes all elements that don't satisfy the predicate:

filter even [1..4] -> [2,4]

So you can build a pipe of mapand filter than or use list-comprehension instead:

map (`div` 2) $ filter even [1..4]
[x `div` 2 | x <- [1..4], even x]

Choose whatever you like best.

百合的盛世恋 2024-10-24 01:31:19

制作你自己的辅助函数生成器:(

ifP pred f x = 
    if pred x then f x
    else x

custom_f = ifP even f
map custom_f [..]

警告:我现在无法访问编译器。我想这可以正常工作......)

Make your own helper function maker:

ifP pred f x = 
    if pred x then f x
    else x

custom_f = ifP even f
map custom_f [..]

(caveat: I don't have access to a compiler right now. I guess this works OK...)

開玄 2024-10-24 01:31:19

我喜欢其他更通用的解决方案,但在你非常特殊的情况下,你可以逃脱

map (\x -> x `div` (2 - x `mod` 2)) [1..4]

I like the other, more general solutions, but in your very special case you can get away with

map (\x -> x `div` (2 - x `mod` 2)) [1..4]
恋你朝朝暮暮 2024-10-24 01:31:19

大部分是对现有答案的抄袭,但根据我对“可读”的有偏见的定义(我更喜欢守卫而不是 ifs,并且 wherelet 更喜欢):

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]

Mostly a rip off of existing answers, but according to my biased definition of "readable" (I like guards more than ifs, and where more than let):

mapIf p f = map f'
    where f' x | p x = f x | otherwise = x

ghci says it probably works

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]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文