Haskell - 按第一个第二个元素排序,然后按第一个元素排序

leo*_*ott 5 sorting haskell

我有一个元组列表,我想按第二个元素(降序)对其进行排序,然后按第一个元素(升序)对其进行排序。

我的代码如下所示:

sortedOcc :: Eq a => [a] -> [(a, Int)]
sortedOcc = sortBy (flip compare `on` snd) . occurences
Run Code Online (Sandbox Code Playgroud)

这是按occurences(function) 返回的列表的第二个元素进行的第一次排序。我应该如何按第一个元素添加第二个排序(升序)?

jpm*_*ier 6

Data.Ord模块提供了一个Down新类型,其目的只是反转顺序。

\n

它还提供了一个comparing功能

\n
comparing :: Ord a => (b -> a) -> b -> b -> Ordering\n
Run Code Online (Sandbox Code Playgroud)\n

必须先输入一些转换函数才能传递给sortBy.

\n

像这样:

\n
$ ghci\n GHCi, version 8.8.4: https://www.haskell.org/ghc/  :? for help\n \xce\xbb> \n \xce\xbb> sortBy  (comparing (\\(a,v) -> (Down v, a)))   [(1,2),(1,3),(5,2),(5,3)]\n [(1,3),(5,3),(1,2),(5,2)]\n \xce\xbb> \n
Run Code Online (Sandbox Code Playgroud)\n

然后,转换函数返回的值使用其自己的 \xe2\x80\x9cnatural\xe2\x80\x9d 顺序进行排序。在我们的例子中,这是字典顺序有序类型对的

\n

总的来说,代码需要一个Ord a约束:

\n
sortedOcc :: Ord a => [a] -> [(a, Int)]\nsortedOcc = sortBy (comparing (\\(a,v) -> (Down v, a)))  .  occurences\n
Run Code Online (Sandbox Code Playgroud)\n