F#从文件读取vs下载字符串并按换行符拆分

F#从文件读取vs下载字符串并按换行符拆分,f#,webclient,sequences,F#,Webclient,Sequences,我不熟悉F#并试图解决这个问题 该文件包含2001/2年英超联赛的结果。标有“F”和“A”的列包含了该赛季每支球队的总进球数(因此阿森纳对对手的进球数为79个,对对手的进球数为36个)。编写一个程序,打印“赞成”和“反对”目标差异最小的团队名称 保存文件并使用file.ReadAllLines读取时,my Solutions工作: open System.IO open System let split (s:string) = let cells = Array.ofSeq(s.Sp

我不熟悉F#并试图解决这个问题

该文件包含2001/2年英超联赛的结果。标有“F”和“A”的列包含了该赛季每支球队的总进球数(因此阿森纳对对手的进球数为79个,对对手的进球数为36个)。编写一个程序,打印“赞成”和“反对”目标差异最小的团队名称

保存文件并使用file.ReadAllLines读取时,my Solutions工作:

open System.IO
open System

let split (s:string) =
    let cells = Array.ofSeq(s.Split([|' '|],StringSplitOptions.RemoveEmptyEntries))    
    (cells.[1], int cells.[6], int cells.[8])

let balance t = 
    let (_,f,a) = t
    -(f-a)

let lines = List.ofSeq(File.ReadAllLines(@"F:\Users\Igor\Downloads\football.dat"));;


lines      
    |> Seq.skip 5       
    |> Seq.filter (fun (s:string) -> s.Split([|' '|],StringSplitOptions.RemoveEmptyEntries).Length = 10)    
    |> Seq.map split    
    |> Seq.sortBy balance    
    |> Seq.take 1
    |> Seq.map (fun (n,_,_) -> printfn "%s" n)
但是,当我使用WebClient和拆分行下载文件而不是读取文件时,其余的代码就不起作用了。序列长度相同,但F#Interactive不显示元素,也不打印输出。代码是

open System.Net
open System

let split (s:string) =
    let cells = Array.ofSeq(s.Split([|' '|],StringSplitOptions.RemoveEmptyEntries))    
    (cells.[1], int cells.[6], int cells.[8])

let balance t = 
    let (_,f,a) = t
    -(f-a)

let splitLines (s:string) = 
    List.ofSeq(s.Split([|'\n'|]))


let wc = new WebClient()
    let lines = wc.DownloadString("http://pragdave.pragprog.com/data/football.dat")


lines   
    |> splitLines   
    |> Seq.skip 5       
    |> Seq.filter (fun (s:string) -> s.Split([|'     '|],StringSplitOptions.RemoveEmptyEntries).Length = 10)    
    |> Seq.map split        
    |> Seq.sortBy balance   
    |> Seq.take 1
    |> Seq.map (fun (n,_,_) -> printfn "%s" n)

有什么区别?List.ofSeq(File.ReadAllLines..)重新运行一个序列并从internet下载该文件,然后将其拆分\n返回的序列与URL返回HTML页面而不是原始数据文件的序列相同,这可能是导致您出现问题的原因吗

此外,验证页面用于换行符的分隔符通常也很好。那一个正在使用
0x0A
,它是
\n
,但有时您会发现
\r\n
或很少
\r

编辑:

另外,您似乎正在使用
map
来处理打印,这不是一个好方法。我知道在一次执行所有操作时,通常很难让您的示例显示输出


我建议映射到
n
并以其他方式打印,例如使用
Seq.head

URL返回的是HTML页面,而不是原始数据文件,这可能是导致问题的原因吗

此外,验证页面用于换行符的分隔符通常也很好。那一个正在使用
0x0A
,它是
\n
,但有时您会发现
\r\n
或很少
\r

编辑:

另外,您似乎正在使用
map
来处理打印,这不是一个好方法。我知道在一次执行所有操作时,通常很难让您的示例显示输出


我建议映射到
n
并以其他方式打印,例如使用
Seq.head

最后一行应该使用Seq.iter而不是Seq.map,并且表达式中有太多空格分隔每一行

通过这些更正,它可以正常工作:

open System.Net
open System
open System.IO

let split (s:string) =
    let cells = Array.ofSeq(s.Split([|' '|],StringSplitOptions.RemoveEmptyEntries))    
    (cells.[1], int cells.[6], int cells.[8])

let balance t = 
    let (_,f,a) = t
    -(f-a)

let splitLines (s:string) = 
    List.ofSeq(s.Split([|'\n'|]))


let wc = new WebClient()
let lines = wc.DownloadString("http://pragdave.pragprog.com/data/football.dat") |> splitLines 

let output =
  lines   
    |> Seq.skip 5   
    |> Seq.filter (fun (s:string) -> s.Split([|' '|],StringSplitOptions.RemoveEmptyEntries).Length = 10)    
    |> Seq.map split        
    |> Seq.sortBy balance   
    |> Seq.take 1
    |> Seq.iter (fun (n,_,_) -> Console.Write(n))

let stop = Console.ReadKey()

最后一行应该使用Seq.iter而不是Seq.map,并且表达式中分隔每一行的空格太多

通过这些更正,它可以正常工作:

open System.Net
open System
open System.IO

let split (s:string) =
    let cells = Array.ofSeq(s.Split([|' '|],StringSplitOptions.RemoveEmptyEntries))    
    (cells.[1], int cells.[6], int cells.[8])

let balance t = 
    let (_,f,a) = t
    -(f-a)

let splitLines (s:string) = 
    List.ofSeq(s.Split([|'\n'|]))


let wc = new WebClient()
let lines = wc.DownloadString("http://pragdave.pragprog.com/data/football.dat") |> splitLines 

let output =
  lines   
    |> Seq.skip 5   
    |> Seq.filter (fun (s:string) -> s.Split([|' '|],StringSplitOptions.RemoveEmptyEntries).Length = 10)    
    |> Seq.map split        
    |> Seq.sortBy balance   
    |> Seq.take 1
    |> Seq.iter (fun (n,_,_) -> Console.Write(n))

let stop = Console.ReadKey()

输入中的html不是问题,这就是为什么我跳过前5行,只处理包含10项的行。第一个工作代码和第二个不工作代码之间的唯一区别是,第一个从文件中读取inut,第二个从internet下载相同的文件并按行拆分。输入中的html不是问题,这就是为什么我跳过前5行,只处理包含10项的行。第一个工作代码和第二个不工作代码之间的唯一区别是,第一个从文件中读取inut,第二个从internet下载相同的文件并将其按行拆分