denna
How to filter a list of nils
I have sometimes list with elements of different type.
for example nil and tuple
the thing is that the filter function is a bit long. I wonder if this can be written shorter. particularly because i don’t care about failing cases.
Enum.filter(list_of_nils_and_tuples, fn elem ->
if(is_nil(elem)) do
false
else
{id, _v} = elem
some_complicated_test(id)
end
end)
The question is maybe more about how to avoid if else structures in elixir?
Most Liked
stefanchrobot
Pattern matching to the rescue!
Enum.filter(list_of_nils_and_tuples, fn
nil -> false
{id, _v} -> some_complicated_test(id)
end)
kokolegorille
You can, but You also apply a transformation at the same time…
list_of_nils_and_tuples
|> Enum.filter(& &1) # drop falsy value
|> Enum.map(& some_complicated_test(elem(&1, 0)))
You can also define some_complicated_test to return false when nil is passed, and use it as the filter function.
kendocode
I just had to do something similar and was looking for something like Enum.compact().
I ended up using a comprehension with pattern matching as well, but you don’t need the match operator (=) or the guard. The {id, _v} itself is already doing the work. Example:
iex(0)> list = [nil, nil, {1,2}, nil, {3,4}]
[nil, nil, {1, 2}, nil, {3, 4}]
iex(1)> for {id, _v} <- list, do: id
[1, 3]
slouchpie
Another option is to to use a comprehension:
for {id, _v} = nil_or_tuple <- list_of_nils_and_tuples, not is_nil(nil_or_tuple), do: some_complicated_test(id)
brettbeatty
You can also filter/reject multiple times, though you may want to use stream instead of enum for longer lists.
list_of_nils_and_tuples
|> Enum.reject(&is_nil/1)
|> Enum.filter(fn {id, _v} -> some_complicated_test(id) end)







