问题描述
我正在寻找一种创建由另一个序列的第n个元素组成的序列的方法,但是似乎没有找到一种以一种优雅的方式完成该任务的方法.我当然可以破解一些东西,但是我想知道是否有一个我没有看到的库函数.
I am looking for a way to create a sequence consisting of every nth element of another sequence, but don't seem to find a way to do that in an elegant way. I can of course hack something, but I wonder if there is a library function that I'm not seeing.
名称以-i结尾的序列函数对于确定元素是第n个元素还是第n个元素的目的似乎是相当不错的,但是我只能看到iteri
和,但没有一个真正适合自己的任务.
The sequence functions whose names end in -i seem to be quite good for the purpose of figuring out when an element is the nth one or (multiple of n)th one, but I can only see iteri
and mapi
, none of which really lends itself to the task.
示例:
let someseq = [1;2;3;4;5;6]
let partial = Seq.magicfunction 3 someseq
然后partial
应该是[3;6]
.那里有类似的东西吗?
Then partial
should be [3;6]
. Is there anything like it out there?
如果我不那么有野心,并且允许n
不变/已知,那么我刚刚发现以下内容应该可以工作:
If I am not quite as ambitious and allow for the n
to be constant/known, then I've just found that the following should work:
let rec thirds lst =
match lst with
| _::_::x::t -> x::thirds t // corrected after Tomas' comment
| _ -> []
有没有办法写得这么短?
Would there be a way to write this shorter?
推荐答案
您可以通过将mapi
与其他功能组合在一起来获得行为:
You can get the behavior by composing mapi
with other functions:
let everyNth n seq =
seq |> Seq.mapi (fun i el -> el, i) // Add index to element
|> Seq.filter (fun (el, i) -> i % n = n - 1) // Take every nth element
|> Seq.map fst // Drop index from the result
Annon建议的使用options和choose
的解决方案将仅使用两个函数,但第一个函数的主体会稍微复杂一些(但原理基本相同).
The solution using options and choose
as suggested by Annon would use only two functions, but the body of the first one would be slightly more complicated (but the principle is essentially the same).
直接使用IEnumerator
对象的更高效的版本并不难写:
A more efficient version using the IEnumerator
object directly isn't too difficult to write:
let everyNth n (input:seq<_>) =
seq { use en = input.GetEnumerator()
// Call MoveNext at most 'n' times (or return false earlier)
let rec nextN n =
if n = 0 then true
else en.MoveNext() && (nextN (n - 1))
// While we can move n elements forward...
while nextN n do
// Retrun each nth element
yield en.Current }
以下代码段也可以在此处找到: http://fssnip.net/1R
The snippet is also available here: http://fssnip.net/1R
这篇关于获取序列的第n个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!