ELM地图/折叠理解

时间:2018-01-06 19:31:25

标签: functional-programming elm fold map-function

我在理解地图或折叠功能时遇到问题。

我有一个输入dht_get_peers_alert的任务,需要将其转换为以下输出:[1,1,2,2,3]。所以基本上我需要做的是从数组中获取元素并检查是否可能将它与其他相同的元素组合在一起。我只需要使用地图或折叠功能。

2 个答案:

答案 0 :(得分:2)

我不确定为什么在主List库中没有包含此函数(或类似的东西),但这里有一个快速而又脏的版本(source

groupBy : List v -> (v -> k) -> List ( k, List v )
groupBy items f =
    case items of
        [] ->
            []

        x :: xs ->
            let
                key =
                    f x

                rest =
                    groupBy xs f
            in
                insertTo rest key x


insertTo : List ( k, List v ) -> k -> v -> List ( k, List v )
insertTo m key value =
    case m of
        [] ->
            [ ( key, [ value ] ) ]

        x :: xs ->
            if Tuple.first x == key then
                [ ( key, value :: Tuple.second x ) ] ++ xs
            else
                x :: insertTo xs key value

然后你可以这样称呼它

groupBy [1, 1, 2, 2, 3] identity

答案 1 :(得分:0)

以下是我提出的建议:


module Main exposing (main)

import Html exposing (Html, text)


main : Html msg
main =
    [ 1, 1, 2, 2, 3, 2, 2, 1, 4 ] |> toGroups |> toString |> text


toGroups : List Int -> List (List Int)
toGroups xs =
    xs
        |> List.sort
        |> List.foldl makeGroups []


makeGroups : Int -> List (List Int) -> List (List Int)
makeGroups x groups =
    let
        this =
            if currentGroupValue == Just x then
                previousGroups ++ [ x::currentGroup ]
            else
                groups ++ [ [ x ] ]

        currentGroupValue =
            List.head currentGroup

        currentGroup =
            groups
                |> List.reverse
                |> List.head
                |> Maybe.withDefault []

        previousGroups =
            takeAllButLast groups

        takeAllButLast xs =
            List.take (List.length xs - 1) xs
    in
    this

所以在高级别我这样做:

  1. 对列表进行排序;
  2. 从相邻的相等元素中创建子列表。
  3. 您可以在此处看到它正在运行并使用它:https://ellie-app.com/7BQCWhW6na1/0

    干杯!