【发布时间】:2014-11-20 08:02:30
【问题描述】:
我遇到一些元素列表xs 并想对每个第 N 个元素做一些事情是很常见的。最简单的例子是 Sieve 或 Erastothenes,您想在其中“剔除”给定素数的每个倍数。我可以做到这一点的两种方法是显式递归传递一个计数器变量;或zipWith ($) (cycle (replicate (n-1) id ++ f))。那么哪种方式更好/更优雅/更常用,或者有没有像mapEveryN :: (a -> a) -> Int -> [a] -> [a]这样的库函数我还没有找到?
【问题讨论】:
-
好吧,你可以使用
zipWith ($) (drop 1 $ cycle $ f : replicate (n - 1) id),这对我来说似乎很优雅。没有显式递归,避免串联,而是使用:,它是一个 1-liner。 -
你也可以通过
piecesOf n = unfoldr (Just . splitAt n)和concatMap获得一个中间列表。可能不像其他方法那样简短高效,但有时会很方便。 -
@n.m.
piecesOf创建由n组成的组,然后是可能小于n的组,然后是无限数量的空组。 -
@pat 是的,它适用于无限列表......为什么有人会满足于更少? :)
-
这可能不是实现eratosphenes 筛子的最佳方法,但你所拥有的作为“适用于每个n 次”的解决方案相当不错,尽管我会这样做@贝克莱尔风格
标签: list haskell repeat sieve-of-eratosthenes circular-list