gpt4 book ai didi

f# - F#中的字典排序

转载 作者:行者123 更新时间:2023-12-04 23:27:38 29 4
gpt4 key购买 nike

我正在玩一个玩具问题(凸 shell 识别)并且已经需要两次字典排序。其中一个案例的列表是type Point = { X: float; Y: float } ,我想按 X 坐标排序,如果相等,则按 Y 坐标排序。
我最终写了以下内容:

let rec lexiCompare comparers a b =
match comparers with
[ ] -> 0
| head :: tail ->
if not (head a b = 0) then head a b else
lexiCompare tail a b

let xComparer p1 p2 =
if p1.X > p2.X then 1 else
if p1.X < p2.X then -1 else
0

let yComparer p1 p2 =
if p1.Y > p2.Y then 1 else
if p1.Y < p2.Y then -1 else
0

let coordCompare =
lexiCompare [ yComparer; xComparer ]

这让我可以做
let lowest (points: Point list) =
List.sortWith coordCompare points
|> List.head

到现在为止还挺好。然而,这感觉有点沉重。我必须创建返回 -1、0 或 1 的特定比较器,到目前为止,我看不到在 List.minBy 之类的情况下使用它的直接方法。理想情况下,我想做一些类似于提供可以比较的函数列表的事情(例如 [(fun p -> pX); (fun p -> pY)])并做一些类似列表的字典序最小化的事情支持该功能列表的项目。

有没有办法在 F# 中实现这一点?还是我想错了?

最佳答案

好吧,首先,您可以依赖 F# 的内置 compare功能:

let xComparer p1 p2 = compare p1.X p2.X
let yComparer p1 p2 = compare p1.Y p2.Y

或者,如果需要,您可以清楚地抽象一下:
let compareWith f a b = compare (f a) (f b)
let xComparer = compareWith (fun p -> p.X)
let yComparer = compareWith (fun p -> p.Y)

或者,如您所见,您可以将此方法直接构建到列表处理函数中:
let rec lexiCompareWith l a b =
match l with
| [] -> 0
| f::fs ->
match compare (f a) (f b) with
| 0 -> lexiCompareWith fs a b
| n -> n

这里的一个重要限制是,由于您将它们放入一个列表中,因此这些函数必须都具有相同的返回类型。这在您的 Point 中不是问题示例(因为两个函数的类型都是 Point -> float ),但它会阻止您对两个 Person 进行排序按名称和年龄排列的对象(因为第一个投影的类型为 Person -> string 但第二个投影的类型为 Person -> int )。

关于f# - F#中的字典排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10051266/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com