如何从列表中获取不同的项目?

How do I get distinct items from a list?

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

我有以下代码:

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

错误:

The definition of topicsFromLinks does not match its type annotation. - The type annotation for topicsFromLinks says it always returns:

List Topic

But the returned value (shown above) is a:

List comparable

我希望以下几行在结构平等方面起作用:

|> Set.fromList
|> Set.toList

为什么我会收到可比较列表?

如何解决这个编译错误?

附录:

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

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

根据 documentation for Set:

The values can be any comparable type. This includes Int, Float, Time, Char, String, and tuples or lists of comparable types.

您正试图将 Topic 值放入只有可比类型才有效的位置。

谢天谢地,有 elm-community/list-extra package which exposes a uniqueBy 函数可以让您指定自己的函数来将某些东西变成可比较的东西。

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

import List.Extra exposing (uniqueBy)

topicsFromLinks : List Link -> List Topic
topicsFromLinks links =
    links
        |> List.map .topics
        |> List.concat
        |> uniqueBy toString

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