获取序列的第n个元素

获取序列的第n个元素

本文介绍了获取序列的第n个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种创建由另一个序列的第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个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 15:09