Mapping over nested lists

I have a model that is a record in which some fields are lists of lists of strings. I’d like to display each item of the nested list in the view. This seems like a simple thing that I’m just not getting right.

myModel = { field1 = ["foo", "bar", "baz"], field2 = [ ["this", "that"], ["the", "other"] ] }

I’m trying to do something like:

List.map Html.text (List.map (\_ x -> x) myModel.field2)

but that doesn’t work due to the second argument to map being a List (String -> String) instead of a List (String).

I’m not sure what your intention with the (\_ x -> x) function is? Are you wanting to print the second entry in each list?

Otherwise, it sounds like you might benefit from concatenating the lists first. So you could do:

myModel.field2 |> List.concat |> List.map Html.text

Which is the same as:

List.map Html.text (List.concat myModel.field2)

You might find that sufficient. If you want to do the second item in each list, it would be more involved.

1 Like

this is pointing to a slight misunderstanding. If you have [ ["foo", "bar"]] you cannot treat the internal list as a list of two arguments because it is not modeled like that. I order to model it like that you need to use tuples.

List.map Html.text (List.map (\(_, x) -> x) [ ("foo", "bar") ]) would work and be equivalent to List.map Html.text (List.map Tuple.first [ ("foo", "bar") ])

if you still want to model it like that, you will need something like:

    List.map
        (\l ->
            case l of
                _ :: x :: [] ->
                    text x

                _ ->
                    text ""
        )
        myModel.field2

or List.map (\l -> List.drop 1 |> List.head |> Maybe.withDefault "" |> text) myModel.filed2

2 Likes

Thanks for the help guys. I ended up restructuring the model to make life simpler but your comments improved my overall understanding. Thanks again.

2 Likes