盆栽エンジニアリング日記

勉強したことをまとめるブログ

Elmでレコードをソートする

Elmで用意されているList.sort関数は、比較関数を渡すことができず、自分で定義したレコードをソートすることができない。
レコードをソートしたい場合は、以下の関数を利用する

  • sortBy
  • sortWith

List.sortBy

List.sortByの関数定義は以下の通り

sortBy : (a -> comparable) -> List a -> List a

ある型aを受け取って、比較可能な型を返す関数を用意する必要がある。
Elmではレコードを作成すると、.<フィールド名>という関数も作成される。
この関数は、レコードを受け取って、<フィールド名>値を返すため、これをsortByに指定すればいい。

type alias Person =
    { name : String
    , age : Int
    }

List.sortBy .name [Person "person1" 10, Person "person2" 20]
=> [{ age = 10, name = "person1" },{ age = 20, name = "person2" }]

List.sortWith

List.sortWithでは、比較関数を自作することで、更に柔軟にソートを行うことができる。 List.sortWithの定義は以下の通り

sortWith : (a -> a -> Order) -> List a -> List a

Orderは、Elmで定義されているカスタム型で、順序関係を表す。

type Order
    = LT    -- 未満
    | EQ     -- 等しい  
    | GT     -- より大きい

sortWithを使用する場合は、他の言語で比較関数を作成するときのように、2つの変数を受け取って、Orderを返す関数を定義すればいい。

type alias Person =
    { name : String
    , age : Int
    }

compare a b =
    if String.length a.name + a.age > String.length b.name + b.age then
        GT
    else if String.length a.name + a.age < String.length b.name + b.age then
        LT
    else
        EQ

List.sortWith compare [Person "person" 10, Person "person2" 10]
=>[{ age = 10, name = "person" },{ age = 10, name = "person2" }]

参考資料

package.elm-lang.org