Addition of a compact_map/2 function to the Enum module

I’m kinda surprised no one has mentioned for comprehensions. When I think of map/flat_map with a filter, that’s where my mind goes. Of course, to some people’s taste, this may be even more golf-y than flat_map :person_shrugging: Here’s how I’d do it in one line, a single pass through the Enumerable, and no extra List.wrap:

iex(29)> for x <- [1, 2, 3, 4], y = x + 1, Integer.is_odd(y), do: y
[3, 5]

edit: I thought of a better example where we use a helper function that may return nil or not which fits more closely with the original situation

iex(30)> odd_to_nil = fn x -> if Integer.is_odd(x), do: nil, else: x end
#Function<42.105768164/1 in :erl_eval.expr/6>
iex(31)> for x <- [1, 2, 3, 4], y = odd_to_nil.(x), do: y
[2, 4]

The main piece to understand are filters in for comprehensions. If you have a clause that is not a generator, it’s a filter. If it evaluates to falsy, then the do block is not executed and the next iteration begins.

9 Likes