如何从列表中选择每个第n个元素 [英] How to select every n-th element from a list

查看:156
本文介绍了如何从列表中选择每个第n个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能存在重复:


简单任务 - 我们有一个列表,并且只想在列表中留下每个第n个元素。
在haskell中最习惯的方式是什么?



关闭我的头顶部,就像这样:

  dr n [] = [] 
dr n(x:xs)= x:(dr n $ drop n xs)

但我有一种强烈的感觉,我正在过度复杂化这个问题。

解决方案

您的解决方案很好,但是这里有三个使用Haskell基础库函数的解决方案。 code> dr1 m = concatMap(取1)。 iterate(drop m)

粗略的说,它不会终止(因为 iterate 永不终止)。所以也许更好的解决方案是使用 unfoldr

  { - #(语法TupleSections# - )
导入Data.Maybe
dr2 m = unfoldr((\ x-> fmap(,drop mx)(listToMaybe x)))

如果您不知道GHC扩展和概念(如函子),那么传递给展开的函数会变得有点难看,下面是该解决方案(未经测试):

  dr2 m = unfoldr((\ x  - > case listToMaybe x 
Nothing - > Nothing
Just i - > Just(i,drop mx)))

如果您不喜欢展开,请考虑使用zip和过滤器:

  dr3 m =地图snd。过滤器((== 1).fst)。 zip(周期[1..m])

评论



了解所有这些解决方案略有不同。学习为什么会让你成为更好的Haskell程序员。 dr1 使用迭代,因此永远不会终止(也许这对无限列表是可以的,但可能不是一个好的整体解决方案):

 > dr1 99 [1..400] 
[1,100,199,298,397 ^ C中断。

dr2 解决方案将显示每个 m th值通过跳过展开的值。展开会将用于下一个展开的值和当前展开的结果传递给单个元组。

 > ; dr2 99 [1..400] 
[1,100,199,298,397]



dr3 解决方案稍微长一些,但对于初学者来说可能更容易理解。首先,以 [1..n,1..n,1..n ...] 的周期标记列表中的每个元素。其次,您只选择标记有 1 的数字,有效地跳过元素的 n-1 。第三你删除标签。

 > dr3 99 [1..400] 
[1,100,199,298,397]


Possible Duplicate:
How to get every Nth element of an infinite list in Haskell?

Simple task - we have a list and want to leave only each nth element in that list. What is the most idiomatic way to do it in haskell?

off the top of my head it is something like:

dr n [] = []
dr n (x : xs) = x : (dr n $ drop n xs)

but I have a strong feeling that I'm overcomplicating the problem.

解决方案

Your solution is fine, but here are three other solutions using functions from Haskell's base library.

dr1 m = concatMap (take 1) . iterate (drop m)

Of coarse, this will never terminate (because iterate never terminates). So perhaps a better solution would be to use unfoldr:

{-# LANGUAGE TupleSections #-}
import Data.Maybe
dr2 m = unfoldr ((\x-> fmap (,drop m x) (listToMaybe x)))

The function you pass to an unfold can get a bit ugly if you don't know GHC extensions and concepts such as functors, here's that solution again without the fancy foot-work (untested):

dr2 m = unfoldr ((\x -> case listToMaybe x of
                         Nothing -> Nothing
                         Just i  -> Just (i,drop m x)))

If you don't like unfolds then consider a zip and a filter:

dr3 m = map snd . filter ((== 1) . fst) . zip (cycle [1..m])

Review

Understand all these solutions are slightly different. Learning why will make you a better Haskell progammer. dr1 uses iterate and will thus never terminate (perhaps this is ok for infinite lists, but probably not a good overall solution):

> dr1 99 [1..400]
[1,100,199,298,397^CInterrupted.

The dr2 solution will show every mth value by skipping values in the unfold. The unfold passes both the value to be used for the next unfolding and the result of the current unfolding in a single tuple.

> dr2 99 [1..400]
[1,100,199,298,397]

The dr3 solution is slightly longer but probably easier for a beginner to understand. First you tag every element in the list with a cycle of [1..n, 1..n, 1..n ...]. Second, you select only the numbers tagged with a 1, effectively skipping n-1 of the elements. Third you remove the tags.

> dr3 99 [1..400]
[1,100,199,298,397]

这篇关于如何从列表中选择每个第n个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆