记录列表中的最大值

时间:2016-06-30 12:57:37

标签: elm

说我有榆树的记录列表:

[ { id = 1, magnitude = 100 }
, { id = 3, magnitude = 300 }
, { id = 2, magnitude = 200 } ]

我希望得到幅度值最大的记录(300)。这样做的好方法是什么?

docs给出了使用"最大值"的示例。 -method,但它使用一个简单的整数列表。它是如何完成记录的?

3 个答案:

答案 0 :(得分:2)

根据@robertjlooby

的推荐,

更新

有一个名为maximumBy的函数,它在elm-community / list-extra中完成了这个功能。例如:

List.Extra.maximumBy .magnitude list

原始答案

有几种方法可以实现这一目标。

第一种方式更简洁,但它涉及对整个列表进行排序,对其进行反转,然后进行整理。

maxOfField : (a -> comparable) -> List a -> Maybe a
maxOfField field =
  List.head << List.reverse << List.sortBy field

如果你想要更高效的东西并且只遍历一次列表,那么这是一个更高效的版本:

maxOfField : (a -> comparable) -> List a -> Maybe a
maxOfField field =
  let f x acc =
    case acc of
      Nothing -> Just x
      Just y -> if field x > field y then Just x else Just y 
  in List.foldr f Nothing

使用它的一个例子:

list =
  [ { id = 1, magnitude = 100 }
  , { id = 3, magnitude = 300 }
  , { id = 2, magnitude = 200 } ]

main =
  text <| toString <| maxOfField .magnitude list

答案 1 :(得分:1)

这是一个使用foldl和默认记录的版本:

bigger =
    let
        choose x y =
            if x.magnitude > y.magnitude then
                x
            else
                y
    in
        List.foldl choose {id = 0, magnitude = 0} items

答案 2 :(得分:1)

塞巴斯蒂安的回答添加了一个任意的起始值,如果你的所有数量都是负数,这可能会导致问题。我会调整到

bigger items =
    case items of 
        [] -> []
        (h :: []) -> h
        (h :: tail) ->
            let
                choose x y =
                    if x.magnitude > y.magnitude then
                        x
                    else
                        y
            in
                List.foldl choose h tail