gpt4 book ai didi

comparison - 如何比较 Elm 中的多个字段?

转载 作者:行者123 更新时间:2023-12-04 02:26:39 25 4
gpt4 key购买 nike

我目前正在用 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)

我的比较规则是(按重要性降序排列):
  • 正确猜测的数量 (asc)
  • 数字总体猜测 (desc)
  • 上次询问单词的时间 (asc)
  • 添加单词时 (desc)

  • 我能想到的最好方法是:
    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)比较日期值(因为 Date 显然不是 comparable )

  • 有没有更优雅/Elm-ish 的方式来实现我想要的?

    更新+解决方案

    正如@“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))

    最佳答案

    多亏了 |>,一种更像 Elm 风格的方法是组合式的。运算符(operator)。
    elm-ordering库提供了执行此类操作所需的原语,尤其是 Ordering.byFieldOrdering.breakTiesWith职能。

    至于日期,我的建议是使用 Date.toTime (结果值具有可比性)。

    奖励:您的订购功能的完整实现可在此处进行测试:https://runelm.io/c/xoz .你可以看到它比你的更简单,更易读......

    关于comparison - 如何比较 Elm 中的多个字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41535288/

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