F# 从文本文件读取和排序

F# 从文本文件读取和排序,f#,F#,我已经设法读取了包含逐行随机数的文本文件。当我使用printfn“%A”行输出行时,我得到seq[“45”;“5435”“34”;…],因此我假设行必须是数据类型列表 open System let readLines filePath = System.IO.File.ReadLines(filePath);; let lines = readLines @"C:\Users\Dan\Desktop\unsorted.txt" 我现在尝试按从低到高对列表进行排序,但它没有.sortBy()方

我已经设法读取了包含逐行随机数的文本文件。当我使用
printfn“%A”行输出行时,我得到
seq[“45”;“5435”“34”;…]
,因此我假设行必须是数据类型列表

open System
let readLines filePath = System.IO.File.ReadLines(filePath);;
let lines = readLines @"C:\Users\Dan\Desktop\unsorted.txt"
我现在尝试按从低到高对列表进行排序,但它没有
.sortBy()
方法。有没有人能告诉我如何手动操作?我曾尝试将其转换为数组进行排序,但不起作用

let array = [||]
let counter = 0
for i in lines do
 array.[counter] = i
 counter +1
Console.ReadKey <| ignore
let数组=[||]
设计数器=0
因为我喜欢排队
数组。[计数器]=i
计数器+1

Console.ReadKey如果所有的行都是整数,您可以使用
Seq.sortBy int
,如下所示:

open System
let readLines filePath = System.IO.File.ReadLines(filePath)
let lines = readLines @"C:\Users\Dan\Desktop\unsorted.txt"
let sorted = lines |> Seq.sortBy int
如果某些行可能不是有效的整数,则需要执行解析和验证步骤。例如:

let tryParseInt s =
    match System.Int32.TryParse s with
    | true, n -> Some n
    | false, _ -> None
let readLines filePath = System.IO.File.ReadLines(filePath)
let lines = readLines @"C:\Users\Dan\Desktop\unsorted.txt"
let sorted = lines |> Seq.choose tryParseInt |> Seq.sort
请注意,我刚才编写的
tryParseInt
函数返回int值,因此我使用
Seq.sort
而不是
Seq.sortBy int
,该函数链的输出将是一个int序列,而不是一个字符串序列。如果您确实需要一个字符串序列,但只需要可以解析为int的字符串,那么您可以这样做:

let tryParseInt s =
    match System.Int32.TryParse s with
    | true, _ -> Some s
    | false, _ -> None
let readLines filePath = System.IO.File.ReadLines(filePath)
let lines = readLines @"C:\Users\Dan\Desktop\unsorted.txt"
let sorted = lines |> Seq.choose tryParseInt |> Seq.sortBy int

请注意我是如何从这个版本的
tryParseInt
返回
s
,这样
Seq.choose
就保留了字符串(但丢弃了所有无法通过
System.Int32.TryParse
验证的字符串)。还有更多的可能性,但这应该给你足够的时间开始。

所有的评论都是有效的,但我更关心的是你非常重要的循环

下面是一个例子:

要阅读所有行:

open System.IO

let file = @"c:\tmp\sort.csv"
let lines = File.ReadAllLines(file)
要对行进行排序,请执行以下操作:
let sorted=Seq.sort行

sorted |>Seq.length//获取行数

sorted |>Seq.map(fun x->x.Length)//迭代所有行并获取每行的长度

您还可以使用列表理解语法:
[对于已排序的l->l.ToUpper()]


Seq
适用于所有类型的集合,但您可以将其替换为数组(可变)或列表(F#List)

这是序列号,不是列表。试一试。那么,它是否看起来像
let sorted=lines.Seq.sortBy
@兰诺<代码>顺序。排序是一个函数,而不是一个方法。这可能是
let sorted=Seq.sortBy int lines
,或者
let sorted=lines |>Seq.sortBy int
。要认识到的一点是,序列是惰性的,只有在需要它们的内容时才会生成它们的内容。然后你只能获得一次seq的内容,否则你会得到“错误:无法从一个封闭的文本阅读器读取”。如果你来自C#背景,那么请记住F#序列与C#中的
IEnumerable
完全相同,注意,其他序列重复生成它们的值是非常好的。您无法重复的只是从
System.IO.File.ReadLines
获得的序列(
IEnumerable
)。如果需要重复运行其值,请通过
让storedLines=lines |>list.ofSeq
(或者
lines |>array.ofSeq
)将其存储在列表或数组中。你想要一个列表还是一个数组取决于:你想要一个单链接列表(F#
列表
类型是一个链接列表),具有O(1)头访问和附加,但具有O(N)随机访问,还是一个具有O(1)随机访问但附加速度慢的数组,
let sorted=Seq.sortBy int lines
效果很好:)+1表示信息,但我只是在排序中为x做了一个
,并输出了每个数字:)