me está gustando esta solución mejor. Genera una nueva secuencia a partir de la secuencia existente (lo que significa que no necesita atravesar toda la secuencia para obtener un resultado; eso es crítico si está haciendo algo como procesamiento de registro, donde no puede llamar cosas como Longitud).
Terminé escribiendo blog post con más detalles sobre cómo llegué aquí.
module Seq =
vamos grouped_by_with_leftover_processing f (f2: 'una lista -> lista <' a> opcional) (s: ss < 'a>) = vamos grouped_by_with_acc rec (f:' a -> 'una lista - > 'una lista de opciones *' una lista) ACC (es decir: IEnumerator < 'a>) = {ss si ie.MoveNext() continuación dejó nextValue, sobras = f ie.Current acc si nextValue.IsSome entonces rendimiento nextValue.¡Valor rendimiento! sobras grouped_by_with_acc f, es decir demás dejar que rem = f2 acc si rems.IsSome luego dió rems.Value } {SEC rendimiento! grouped_by_with_acc f [] (s.GetEnumerator())}
vamos YieldReversedLeftovers (f: 'una lista) = si f.IsEmpty entonces ninguno otra cosa Algunos (List.rev f)
Let grouped_by fs = grouped_by_with_leftover_processing YieldReversedLeftovers Fs
dejar que group_by_length_n ns = dejó grouping_function nuevoValor acc = deja que newList = nuevoValor :: acc // Si tenemos la longitud correcta, volver // a Algunos como el primer valor. Eso va a // ser cedido por la secuencia. if List.length acc = n - 1 luego Some (List.rev newList), [] // Si no tenemos la longitud correcta, // use None (por lo que no se producirá nada) else Ninguno , newList
secuencias grandes grouped_by grouping_function s no son un problema:
ss {for i en 1..1000000000 - > i} | > Seq.group_by_length_n 3 ;; val it: seq < lista int > = seq [[1; 2; 3]; [4; 5; 6]; [7; 8; 9]; [10; 11; 12]; ...] >
Gran respuesta. Estaba cerca de esto con mi código pero no lo tenía. – gradbot