按Elm中的第一个索引对元组列表进行排序

Ada*_*ler 4 sorting comparison list elm

假设我有一个类似于以下示例的元组列表:

[(5, "a"), (1, "c"), (7, "d")] 
Run Code Online (Sandbox Code Playgroud)

在Elm中,我该如何按照其第一元素的升序对列表进行排序,以便获得以下结果?

[(1, "c"), (5, "a"), (7, "d")]
Run Code Online (Sandbox Code Playgroud)

使用Elm List文档,看来sortBysortWith函数在这种情况下将很有用。我的实现尝试如下:

maxTuples : Tuple(a, b) -> Tuple(a, b) -> Tuple(a, b)
maxTuples t1 t2 = 
    case compare t1 t2 of 
        ((Tuple.first t1) >= (Tuple.first t2)) -> GT
         _                                     -> LT


sortByFirst : List (Tuple (a, b)) -> List (Tuple (a, b))
sortByFirst lst = 
    List.sortWith maxTuples lst
Run Code Online (Sandbox Code Playgroud)

但是,我遇到了以下性质的编译器错误:

I ran into something unexpected when parsing your code!

99|         ((Tuple.first t1) >= (Tuple.first t2)) -> GT
                ^
I am looking for one of the following things:

an upper case name
Run Code Online (Sandbox Code Playgroud)

我的直觉是,编译器正在寻找GT/ LT/ EQ每次完成的API List库,但如果我不知道我们如何能够为使用的情况下sortBysortWith通过的第一个索引排序元组的列表中榆树每个元素。

Jan*_*nar 5

您找到了正确的功能。在您的代码中,实际上存在多个问题:

  1. 类型注释应该是正义的(a, b),而不是Tuple(a, b)
  2. 你比较t1t2,这将字典序比较的元组。你真的想要compare (Tuple.first t1) (Tuple.first t2)
  3. case分支需要之前的模式->。在这种情况下,将类似于EQ,因为您要匹配compare返回的Order类型的结果。

您可以像这样修复代码:

maxTuples : (comparable, b) -> (comparable, b) -> (comparable, b)
maxTuples t1 t2 = 
    case compare (Tuple.first t1) (Tuple.first t2) of 
        GT -> GT
        EQ -> EQ
         _ -> LT
Run Code Online (Sandbox Code Playgroud)

但是现在有了不必要的重复,您只是在返回compare函数的结果。

maxTuples t1 t2 = 
    compare (Tuple.first t1) (Tuple.first t2)
Run Code Online (Sandbox Code Playgroud)

与sort函数一起,它看起来像这样:

sortByFirst lst = 
    List.sortWith (\t1 t2 -> compare (Tuple.first t1) (Tuple.first t2)) lst
Run Code Online (Sandbox Code Playgroud)

事实证明,这种操作非常普遍,尤其是在记录列表中。因此,Elm提供了另一个功能– sortBy。它采用一个函数并在应用该函数后比较元素:

sortBy f lst =
    List.sortWith (\a b -> compare (f a) (f b)) lst
Run Code Online (Sandbox Code Playgroud)

因此,您可以使用sortBy函数大大简化代码:

sortByFirst : List (comparable, b) -> List (comparable, b)
sortByFirst =
    sortBy Tuple.first
Run Code Online (Sandbox Code Playgroud)