从文本文件中读取并排序

时间:2017-01-13 08:28:56

标签: f#

我设法读取了包含逐行随机数的文本文件。当我使用printfn "%A" lines输出行时,我得到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

提前致谢。

2 个答案:

答案 0 :(得分:5)

如果所有行都是整数,则可以使用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

如果某些行可能不是有效整数,那么您需要运行解析和验证步骤。 E.g:

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,并且该函数链的输出将是一个序列整数而不是一串字符串。如果你真的想要一个字符串序列,但只有那些可以解析为整数的字符串,你可以这样做:

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

请注意我是如何从此版本的s返回tryParseInt的,以便Seq.choose保留字符串(但丢弃任何无法通过{{}验证的字符串1}})。还有更多的可能性,但这应该足以让你开始。

答案 1 :(得分:1)

所有评论都是有效的,但我更担心你的命令性循环。

以下是一个例子:

阅读所有内容:

open System.IO

let file = @"c:\tmp\sort.csv"
let lines = File.ReadAllLines(file)

排序: let sorted = Seq.sort lines

sorted |> Seq.length // to get the number of lines
sorted |> Seq.map (fun x -> x.Length) // to iterate over all lines and get the length of each line

您还可以使用列表推导语法:
[for l in sorted -> l.ToUpper()]

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