Search code examples
elm

Count instances of item


For example the input

["a", "b", "b", "c", "a"]

would lead to the output

[("a", 2), ("b", 2), ("c", 1)]

I can't really think of a functional way to do this in elm


Solution

  • Using existing code is a great idea, but I think it also makes sense to see the concepts:

    To solve the requirement, you traverse the list using a recursive function and build an intermediary data structure. In this case a dictionary because it fits well to counting the occurrences of a string. Then after the list was traversed and all elements were counted, you transform it to the list of tuples.

    Full code on https://ellie-app.com/cLBnWHSBj5ta1

    gather : List comparable -> Dict comparable Int -> List ( comparable, Int )
    gather list dict =
        case list of
            [] ->
                Dict.toList dict
    
            first :: rest ->
                let
                    count =
                        case Dict.get first dict of
                            Just value ->
                                value + 1
    
                            Nothing ->
                                1
                in
                Dict.insert first count dict
                    |> gather rest
    

    Most people like to use fold instead of case-ing on the list, the ellie example also contains that code.

    But the approach is the same: Solve the trivial case first (empty list) and then recurse the function until you meet the trivial case.