什么是从标准输入读取的最佳方式?
我目前正在努力学习F#,并且我正在使用codingame作为编程测验的来源。什么是从标准输入读取的最佳方式?
大部分quizess涉及从标准输入读取一些值,就像stdin中的前十个值是整数,接下来的五个值将是字符串。
目前,我使用这个函数来读取数据,但它感觉非常“un-f#”。
let N = 5
let Reader i =
Console.In.ReadLine()
let words = [0..N-1] |> Seq.map Reader
如果我有阅读给定类型的给定的数字,我就喜欢写东西
open System
let read parser =
Seq.initInfinite (fun _ -> Console.ReadLine())
|> Seq.choose (parser >> function true, v -> Some v | _ -> None)
然后其可用于
let ints = read Int32.TryParse
let ``ten floats`` = read Double.TryParse |> Seq.take 10
注意,如果seq
使用多次,ReadLine()
再次调用:
let anInt = ints |> Seq.take 1
printfn "%A" anInt
printfn "%A" anInt // need to input an int again
其可以通过使用例如被处理List
或Seq.cache
。
对于字符串,它永远不会失败,使用
let strings = read (fun s -> true, s)
,如果你有一个最小长度要求:
let potentialPasswords = read (fun s -> s.Length > 10, s)
我真的很喜欢你在这里展示的作品,谢谢! –
从注释中,很明显,你最喜欢的“F#-native”(我们称之为“地道F#”)从控制台读取的方式。
你有什么是地道的就够了,除了功能,按照惯例,通常用小写字母开头:
let reader i = Console.ReadLine()
另外,因为你不使用参数,你不必给它一个名字:
let reader _ = Console.ReadLine()
如果功能足够小,可以在线写,匿名:
let words = [0..N-1] |> Seq.map (fun _ -> Console.ReadLine())
另外,由于您实际上并未使用索引,因此您可以将列表声明为1..N
而不是0..N-1
。看起来有点干净。
最后,F#提供,你可以用它来实现更好的可读性非常方便列表解析:
let N = 5
let words = [for _ in 1..N -> Console.ReadLine()]
非常好的答案谢谢你 - 我采取了另一个答案,因为我喜欢直接解析数据的能力,但我更喜欢你的解释 - 虽然是通话。 –
请注意F#中特殊的stdin值,它可以用作快捷方式:'stdin.ReadLine()'。还有一个'stdout.WriteLine()'。关于这些的一件好事就是你甚至不需要“打开系统”。 – TheQuickBrownFox
什么是你的问题? –
@MarkSeemann什么是更好的方式从标准输入读取N次? –
我通常会让'words = [for _ in 1 ... N - > Console.ReadLine()]'或者其他的(取决于游戏)。但是我同意@MarkSeemann:不清楚问题是什么。 –