let aBunch = 1000 let offset = 0 let getIt offset = MyIEnumerable |> Seq.skip aBunch * offset |> Seq.take aBunch |> Seq.iter ( .. some processing ...) Calling getIt() with different offsets eventually gives me an 'Invalid operation' exception with additional info that 'the input sequence had insufficient elements' I try to understand why, as both the Seq.Skip and Seq.take do not generate an exception according to the online documentation FSharp CollectionsVersion: (Visual Studio 2010) Beta 1
5 Réponses :
SEQ.SKIP et SEQ.take lancera cette exception si elle s'appelle une valeur supérieure à la séquence. Vous pouvez vérifier le code source dans seq.fs pour voir pourquoi:
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 }
Je sais que c'est une vieille question, mais au cas où quelqu'un vient à travers cela dans une recherche de la façon dont je l'ai fait: p>
Vous pouvez utiliser Seq.trunate si Vous voulez au plus n em> articles. Il ne lancera pas une exception si moins que les articles n em> sont disponibles. P>
Ceci s'applique uniquement à la partie code> seq.take code> de la question, pas seq.skip code>, je suppose?
pour un combiné avec EXCEPTER code> Vous pouvez ajouter votre propre version au module SEQ, comme ceci: seq.trunate code> (qui est un équivalent d'équivalent SEQ.take de code> - il prendra autant d'articles disponibles sans lancer une exception). P> [1..10]
|> Seq.skipSafe 20
|> Seq.truncate 5
(* returns empty seq *)
Voici une implémentation de "Skipsafe" légèrement plus courte à l'aide de fonctions intégrées:
|> Seq.zip (Seq.initInfinite id) |> Seq.skipWhile (fun (i, _) -> i < num) |> Seq.map snd
module Seq =
let trySkip count source =
source |> Seq.indexed |> Seq.filter(fst >> (<=) count) |> Seq.map snd
La documentation ne dit rien des exceptions; Les documents sont incomplets. Je déposerai un bogue DOC.