[英]In Haskell, what is the most common way to apply a function to every Nth element of a list?
Its very common where I come across some list of elements xs
and want to do something to do something with every Nth element. 在我遇到元素
xs
一些列表并想对第N个元素进行操作时,这是很常见的。 The simplest example would be the Sieve or Erastothenes, where you want to "knock out" every multiple of a given prime. 最简单的示例是筛子或Erastothenes,您要在其中“敲除”给定质数的每个倍数。 The two ways I could do this would be explicit recursion passing along a counter variable;
我可以采用的两种方式是通过计数器变量进行显式递归。 or
zipWith ($) (cycle (replicate (n-1) id ++ f))
. 或
zipWith ($) (cycle (replicate (n-1) id ++ f))
。 So which way is better/more elegant/more commonly used, or is there some library function like mapEveryN :: (a -> a) -> Int -> [a] -> [a]
that I haven't found? 那么哪种方法更好/更优雅/更常用,还是有一些我
mapEveryN :: (a -> a) -> Int -> [a] -> [a]
库函数,例如mapEveryN :: (a -> a) -> Int -> [a] -> [a]
?
As you and bheklilr mention, cycle
provides a nice way to accomplish this. 正如您和bheklilr所提到的,
cycle
提供了一种实现此目标的好方法。 You can take advantage of laziness a bit though: 您可以稍微利用懒惰:
mapEvery :: Int -> (a -> a) -> [a] -> [a]
mapEvery n f = zipWith ($) (drop 1 . cycle . take n $ f : repeat id)
The use of zipWith
and cycle
seems more idiomatic (complex behavior composed from simpler behaviors) than a hand-written recursive function that combines both tasks. 与组合了两个任务的手写递归函数相比,使用
zipWith
和cycle
似乎更习惯(由简单行为组成的复杂行为)。
Note : tail
here makes this function undefined for n = 0
so drop 1
is preferable. 注意 :此处的
tail
使该函数在n = 0
不确定,因此最好使用drop 1
。
There isn't a library function for this that I'm aware of. 我知道没有为此提供的库函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.