【问题标题】:How do I get distinct items from a list?如何从列表中获取不同的项目?
【发布时间】:2017-11-10 12:58:29
【问题描述】:

我不清楚如何从列表中检索不同的项目。

我有以下代码:

topicsFromLinks : List Link -> List Topic
topicsFromLinks links =
    links
        |> List.map (\l -> l.topics)
        |> List.concat
        |> Set.fromList
        |> Set.toList

错误:

topicsFromLinks 的定义与其类型不匹配 注解。 - topicsFromLinks 的类型注释总是这样说 返回:

List Topic

但是返回的值(如上图)是:

List comparable

我希望以下几行仅适用于结构平等:

|> Set.fromList
|> Set.toList

为什么我会收到一个可比对象列表?

如何解决这个编译错误?

附录:

type alias Topic =
    { name : String, isFeatured : Bool }

type alias Link =
    {
    ...
    , topics : List Topic
    ...
    }

【问题讨论】:

    标签: elm


    【解决方案1】:

    根据documentation for Set

    这些值可以是任何可比较的类型。这包括 Int、Float、Time、Char、String 以及可比较类型的元组或列表。

    您正试图将 Topic 值放入只有可比较类型才能工作的地方。

    谢天谢地,有一个 elm-community/list-extra 包,它公开了一个 uniqueBy 函数,让您可以指定自己的函数来将某些东西变成可比较的。

    如果您想获得不同的主题列表,同时匹配nameisFeatured 字段,那么您可以使用toString 将值序列化为可比较的值:

    import List.Extra exposing (uniqueBy)
    
    topicsFromLinks : List Link -> List Topic
    topicsFromLinks links =
        links
            |> List.map .topics
            |> List.concat
            |> uniqueBy toString
    

    【讨论】:

      【解决方案2】:

      在 2021 年,与其使用外部库并编写笨拙的 toString 方法(因为 Debug.toString 不再可用于生产用途),不如考虑使用折叠:

      unique : List a -> List a
      unique list =
          List.foldl
              (\a uniques ->
                  if List.member a uniques then
                      uniques
      
                  else
                      uniques ++ [ a ]
              )
              []
              list
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多