简体   繁体   English

在Haskell中,最常见的将函数应用于列表的第N个元素的方法是什么?

[英]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. 与组合了两个任务的手写递归函数相比,使用zipWithcycle似乎更习惯(由简单行为组成的复杂行为)。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM