1

我是 F# 新手,正在尝试解决这个Kata

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

保存文件并使用 File.ReadAllLines 读取文件时,我的解决方案有效:

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..) 重新调整序列并从互联网下载文件并将其拆分为 \n 返回相同的序列

4

2 回答 2

1

最后一行应该使用 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()
于 2012-08-02T08:30:59.583 回答
0

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

此外,通常最好验证页面用于换行符的分隔符。那个是用0x0Awhich is \n,但有时你会发现\r\n还是很少\r

编辑:

此外,您似乎正在使用map处理打印,这不是一个好方法。我知道我一般很难让您的样本在一次执行时显示输出。

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

于 2012-08-01T21:09:17.827 回答