Take every Nth element of sequence

A function that takes every Nth element of a sequence where N is passed as an argument. The snippet shows a naive function and a function using IEnumerator directly to provide an efficient implementation.

Copy Source
Copy Link
Tools:

Composing existing functions

1: let everyNth n seq = 
2:   seq |> Seq.mapi (fun i el -> el, i)              // Add index to element
3:       |> Seq.filter (fun (el, i) -> i % n = n - 1) // Take every nth element
4:       |> Seq.map fst                               // Drop index from the result

Efficient version using enumerator

 1: let everyNth n (input:seq<_>) = 
 2:   seq { use en = input.GetEnumerator()
 3:         // Call MoveNext at most 'n' times (or return false earlier)
 4:         let rec nextN n = 
 5:           if n = 0 then true
 6:           else en.MoveNext() && (nextN (n - 1)) 
 7:         // While we can move n elements forward...
 8:         while nextN n do
 9:           // Retrun each nth element
10:           yield en.Current }
val everyNth : int -> seq<'a> -> seq<'a>

Full name: Snippet.Simple.everyNth
val n : int

  type: int
  implements: System.IComparable
  implements: System.IFormattable
  implements: System.IConvertible
  implements: System.IComparable<int>
  implements: System.IEquatable<int>
  inherits: System.ValueType
Multiple items
val seq : seq<'a>

  type: seq<'a>
  inherits: System.Collections.IEnumerable


--------------------

type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>

  type: seq<'T>
  inherits: System.Collections.IEnumerable
module Seq

from Microsoft.FSharp.Collections
val mapi : (int -> 'T -> 'U) -> seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.mapi
val i : int

  type: int
  implements: System.IComparable
  implements: System.IFormattable
  implements: System.IConvertible
  implements: System.IComparable<int>
  implements: System.IEquatable<int>
  inherits: System.ValueType
val el : 'a
val filter : ('T -> bool) -> seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.filter
val map : ('T -> 'U) -> seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val fst : ('T1 * 'T2) -> 'T1

Full name: Microsoft.FSharp.Core.Operators.fst
val everyNth : int -> seq<'a> -> seq<'a>

Full name: Snippet.Efficient.everyNth
val input : seq<'a>

  type: seq<'a>
  inherits: System.Collections.IEnumerable
Multiple items
val seq : seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------

type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>

  type: seq<'T>
  inherits: System.Collections.IEnumerable
val en : System.Collections.Generic.IEnumerator<'a>

  type: System.Collections.Generic.IEnumerator<'a>
  inherits: System.IDisposable
  inherits: System.Collections.IEnumerator
System.Collections.Generic.IEnumerable.GetEnumerator() : System.Collections.Generic.IEnumerator<'a>
val nextN : (int -> bool)
System.Collections.IEnumerator.MoveNext() : bool
property System.Collections.Generic.IEnumerator.Current: 'a

More information

Link: http://fssnip.net/1R
Posted: 3 years ago
Author: Tomas Petricek (website)
Tags: sequence, seq