代码之家  ›  专栏  ›  技术社区  ›  Moonlight

呼叫Seq.skip和Seq.take in F#

  •  9
  • Moonlight  · 技术社区  · 16 年前
    let aBunch = 1000
    let offset = 0
    
    let getIt offset =
      MyIEnumerable
      |> Seq.skip aBunch * offset
      |> Seq.take aBunch
      |> Seq.iter ( .. some processing ...)
    

    我试图理解为什么Seq.Skip和Seq.take都没有根据在线文档生成异常 FSharp Collections

    版本:(Visual Studio 2010)Beta 1

    5 回复  |  直到 15 年前
        1
  •  24
  •   Joel Mueller    15 年前

    我知道这是一个老问题,但如果有人在搜索时遇到我这样的问题:

    你可以用 Seq.truncate 如果你最多想要 n个 项目。如果少于 n个

        2
  •  7
  •   Dustin Campbell    16 年前

    如果调用的值大于序列,Seq.skip和Seq.take都将引发此异常。您可以检查Seq.fs中的源代码以了解原因:

    let skip count (sequence: seq<_>) =
        { use e = sequence.GetEnumerator() 
          let latest = ref (Unchecked.defaultof<_>)
          let ok = ref false
          for i in 1 .. count do
              if not (e.MoveNext()) then 
                  raise <| System.InvalidOperationException "the input sequence had insufficient elements" 
          while e.MoveNext() do
              yield e.Current }
    
    let take count (sequence : seq<'T>)    = 
        if count < 0 then invalidArg "count" "the number of elements to take may not be negative"
        (* Note: don't create or dispose any IEnumerable if n = 0 *)
        if count = 0 then empty else  
        { use e = sequence.GetEnumerator() 
          for i in 0 .. count - 1 do
              if not (e.MoveNext()) then
                  raise <| System.InvalidOperationException "the input sequence had insufficient elements" 
              yield e.Current }
    
        3
  •  3
  •   krdx    11 年前

    skip 您可以将自己的版本添加到Seq模块,如下所示:

    module Seq =
        let skipSafe (num: int) (source: seq<'a>) : seq<'a> =
            seq {
                use e = source.GetEnumerator()
                let idx = ref 0
                let loop = ref true
                while !idx < num && !loop do
                    if not(e.MoveNext()) then
                        loop := false
                    idx := !idx + 1
    
                while e.MoveNext() do
                    yield e.Current 
            }
    

    结合 Seq.truncate (这是一个例外 Seq.take 相当于-它将在不引发异常的情况下使用尽可能多的可用项)。

    [1..10] 
    |> Seq.skipSafe 20
    |> Seq.truncate 5
    
    (* returns empty seq *)
    
        4
  •  3
  •   user3908642    9 年前

    下面是一个使用内置函数的略短的“skipSafe”实现:

    module Seq =
        let skipSafe num = 
            Seq.zip (Seq.initInfinite id)
            >> Seq.skipWhile (fun (i, _) -> i < num)
            >> Seq.map snd
    

    或者,如果您希望直接将其嵌入到当前管道中,请替换

    |> Seq.skip num
    

    具有

    |> Seq.zip (Seq.initInfinite id)
    |> Seq.skipWhile (fun (i, _) -> i < num)
    |> Seq.map snd
    
        5
  •  1
  •   Sergii    9 年前
    module Seq = 
        let trySkip count source  =
            source |> Seq.indexed |> Seq.filter(fst >> (<=) count) |> Seq.map snd
    
    推荐文章