me gustaría escribir una función que filtra una secuencia utilizando un predicado pero el resultado debería incluir también el primer elemento para el que el predicado devuelve falso.cómo hacer Seq.takeWhile + un elemento en F #
La lógica sería algo como esto, si había una palabra clave rotura en F #
let myFilter predicate s =
seq {
for item in s do
yield item
if predicate item then
break
}
Probé combinaciones de Seq.takeWhile y Seq.skipWhile, algo como esto:
Seq.append
(Seq.takeWhile predicate s)
(Seq.skipWhile predicate s |> Seq.take 1)
... pero el problema es que el primer elemento que coincide con el predicado se pierde entre takeWhile y skipWhile
También tenga en cuenta que la secuencia de entrada es floja por lo que cualquier sol la consumición de la secuencia y la toma de decisiones posteriores no es viable.
¿Alguna idea?
Gracias!
EDITAR: ¡Muchas gracias por todas las respuestas! No esperaba tantas respuestas tan rápido. Echaré un vistazo a cada uno de ellos pronto. Ahora solo quiero dar un poco más de contexto. Considere el kata siguiente codificación que implementa un shell: "! Adiós"
let cmdProcessor state = function
| "q" -> "Good bye!"
| "h" -> "Help content"
| c -> sprintf "Bad command: '%s'" c
let processUntilQuit =
Seq.takeWhile (fun cmd -> cmd <> "q")
let processor =
processUntilQuit
>> Seq.scan cmdProcessor "Welcome!"
module io =
let consoleLines = seq { while true do yield System.Console.ReadLine() }
let display : string seq -> unit = Seq.iter <| printfn "%s"
io.consoleLines |> processor|> io.display
printf "Press any key to continue..."
System.Console.ReadKey()|> ignore
Esta aplicación tiene el problema de que no se de impresión cuando se ingresa el comando q.
Lo que quiero hacer es poner en práctica la función processUntilQuit tal que procesa todos los comandos hasta que "q", incluyendo "q".
¿Qué quiere decir con * el problema es que el primer elemento que coincide con el predicado se pierde entre takeWhile y skipWhile *? Su solución es correcta porque el primer elemento falso todavía está allí en 's'. – pad
@pad: Así que si puedo implementar la processUntilQuit función como esta: vamos processUntilQuit cmds = vamos isNotFinished cmd cmd = <> "q" ss {rendirá! Seq.takeWhile isNotFinished cmds rendimiento! Seq.skipWhile isNotFinished cmds |> Seq.truncate 1} ... el resultado es el siguiente: ¡Bienvenido! q q ¡Adiós! Presione cualquier tecla para continuar ... Como puede ver, tuve que escribir q dos veces para salir. – vidi