我想编写一个函数,它使用谓词过滤序列,但结果还应该包括谓词返回 false 的第一项。
如果在 F# 中有一个 break 关键字,逻辑将是这样的
let myFilter predicate s =
seq {
for item in s do
yield item
if predicate item then
break
}
我尝试了 Seq.takeWhile 和 Seq.skipWhile 的组合,如下所示:
Seq.append
(Seq.takeWhile predicate s)
(Seq.skipWhile predicate s |> Seq.take 1)
...但问题是与谓词匹配的第一项在 takeWhile 和 skipWhile 之间丢失
另请注意,输入序列是惰性的,因此任何消耗该序列并随后做出决定的解决方案都是不可行的。
有任何想法吗?
谢谢!
编辑:非常感谢所有的答案!没想到这么快就有这么多回复。我很快就会看看他们中的每一个。现在我只想提供更多背景信息。考虑以下实现 shell 的编码 kata:
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
这个实现的问题是它不打印“再见!” 输入命令 q 时。
我想要做的是实现函数processUntilQuit以便它处理直到“q”的所有命令,包括“q”。