我目前正在Elm写一个基于网络的词汇训练师。这需要通过自定义比较器对单词列表进行排序。
我想要排序的类型是:
type alias Word =
{ id: Int
, sourceWord: String
, targetWord: String
, numTries: Int
, numCorrect: Int
, createdAt: Maybe Date -- might be empty, therefore wrapped in Maybe
, lastAskedAt: Maybe Date -- might be empty, therefore wrapped in Maybe
}
类型别名WordList = List(Word)
我的比较规则是(按重要性降序排列):
我能想出的最佳方法是:
compareWords: Word -> Word -> Basics.Order
compareWords w1 w2 =
let
dateToComparable d = Date.Format.format "%Y-%m-%d" d
orderNumCorrect = compare w1.numCorrect w2.numCorrect
orderNumTries = compare w2.numTries w1.numTries -- switch ordering to sort descending
orderLastAskedAt = case (w1.lastAskedAt, w2.lastAskedAt) of
(Just a1, Just a2) -> compare (dateToComparable a1) (dateToComparable a2)
(Nothing, Just _) -> Basics.LT
(Just _, Nothing) -> Basics.GT
(Nothing, Nothing) -> Basics.EQ
orderCreatedAt = case (w2.createdAt, w1.createdAt) of -- switch ordering to sort descending
(Just a1, Just a2) -> compare (dateToComparable a1) (dateToComparable a2)
(Nothing, Just _) -> Basics.LT
(Just _, Nothing) -> Basics.GT
(Nothing, Nothing) -> Basics.EQ
in
case orderNumCorrect of
Basics.EQ -> case orderNumTries of
Basics.EQ -> case orderLastAskedAt of
Basics.EQ -> orderCreatedAt
_ -> orderLastAskedAt
_ -> orderNumTries
_ -> orderNumCorrect
我不喜欢出于以下几个原因:
Date.Format.format
(来自mgold / elm-date-format)来比较日期值(因为日期显然不是comparable
)是否有更优雅/榆树的方式来实现我想要的目标?
更新+解决方案
As @" Zimm i48"在他们最优秀的答案中提出,这是一个使用elm-ordering package的更短的版本:
dateToComparable : Maybe Date -> Time
dateToComparable =
Maybe.map Date.toTime >> Maybe.withDefault 0
compareWords : Ordering Word
compareWords =
Ordering.byField .numCorrect
|> Ordering.breakTiesWith (Ordering.byField (.numTries >> negate))
|> Ordering.breakTiesWith (Ordering.byField (.lastAskedAt >> dateToComparable))
|> Ordering.breakTiesWith
(Ordering.byField (.createdAt >> dateToComparable >> negate))
答案 0 :(得分:5)
由于|>
运算符,更多Elm-ish执行此类操作的方式是在组合上。
elm-ordering库提供了执行此类操作所需的基元,尤其是Ordering.byField
和Ordering.breakTiesWith
函数。
关于日期,我的建议是使用Date.toTime
(结果值具有可比性)。
奖励:完全实施您可在此处测试的订购功能:https://runelm.io/c/xoz。你可以看到它比你的更简单,更易读......