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做了一个,并输出了每个数字:)