14

I'd like to define the following function:

compactAndConvertToList : Array (Maybe String) -> List String

This function should remove all Nothing appearances in the given array, and convert it to List.

I came up with the solution below, but it feels dirty a bit.

Is there a better way to achieve this?

import Graphics.Element exposing (..)
import Array

model : Array.Array (Maybe String)
model = Array.fromList [ Just "Hello", Just "Stack", Nothing, Just "Overflow" ]


compactAndConvertToList : Array.Array (Maybe String) -> List String
compactAndConvertToList maybeStrings =
  maybeStrings
    |> Array.filter (\x -> x /= Nothing)
    |> Array.map (Maybe.withDefault "")
    |> Array.toList


main = 
  model
    |> compactAndConvertToList
    |> show
2
  • why are there () around Maybe string? I'm new to elm. Why (Maybe String) and what does that do to Array.Array? Commented Jul 28, 2018 at 14:42
  • @PositiveGuy Without parenthesis around Maybe String, it would be interpreted as two separate arguments for Array. Commented Aug 4, 2020 at 4:13

2 Answers 2

25

If your final result is a list, you are probably better to just convert your array to a list, and then operate on it.

import Array 

compactAndConvertToList : Array.Array (Maybe String) -> List String
compactAndConvertToList = Array.toList >> List.filterMap identity

If you're not comfortable with higher-order functions, you could write it like this:

compactAndConvertToList arr = List.filterMap identity (Array.toList arr)

We take our array, apply toList to it, then apply filterMap with it. Filter map takes a function which produces a maybe, and applies it to every element in the list, discarding the Nothing cases. We just apply the identity functions, which discards the Nothing values that are already there.

In general, Arrays are good for fast random access, but if you're traversing the entire collection a bunch of times, Lists will tend to be faster. But, always start by doing it the clear way, then optimize if you need to.

2
  • Thanks a lot! I like the first version with >>. Somewhat unrelated questions regarding Array vs List: To build a model representing a 2 dimensional array (for this game, for example), is it better to use Array of Arrays? I couldn't find how to get an item at a specific index in a List. Commented Oct 13, 2015 at 4:24
  • Yeah, you definitely don't want lists for that, looking up a specific element is very slow. Array of Arrays is your best bet. Commented Oct 13, 2015 at 4:29
10

Maybe this is a better answer as in 2018. Use an elm-community/maybe-extra package.

Example:

Maybe.Extra.values [Just 1, Nothing, Just 3]

Returns:

[1,3]

Not the answer you're looking for? Browse other questions tagged or ask your own question.