Hello,
I’m trying to create a new list from a map I’m given like so
Enum.map(params, fn {k,v} -> if String.contains?(k, "checklist") and v != "", do: v end)
but the result is list = [nil,nil,nil,nil, 5,3,2] when I just want it to be [5,3,2]. Is there a way to get this result?
NobbZ
May 7, 2019, 5:04am
2
Enum.filter/2
after mapping.
Something like this:
params
|> Enum.map(fn {k, v} -> String.contains?(k, "checklist") and v != "", do: v end)
|> Enum.filter(&(&1 != nil))
Or, to reduce the conditionals, turn it around like this:
params
|> Enum.filter(fn {k, v} -> String.contains?(k, "checklist") and v != "" end)
|> Enum.map(fn {_, v} -> v end)
2 Likes
@NobbZ very cool.
What does the (&(&1 != nil)) denote in your first example?
NobbZ
May 7, 2019, 5:13am
4
Its creating an anonymous function using the capture operator .
It is equivalent to fn x -> x != nil end
but less verbose if you don’t need pattern matching.
1 Like
sf8193:
Enum.map(params, fn {k,v} → if String.contains?(k, “checklist”) and v != “”, do: v end)
Use Kernel.SpecialForms.for/1
comprehension.
for {k, v} <- params, String.contains?(k, "checklist"), v != "", do: v
7 Likes
Yeah I’d use either for
or flat_map
. map
and filter
are both just special-cases of the generic flat_map, which can do both all at once and it is single-pass:
params
|> Enum.flat_map(fn {k, v} -> if(String.contains?(k, "checklist") and v != "", do: [v], else: []) end)
And @mudasobwa ’s for
is great.
4 Likes
@mudasobwa @NobbZ never thought such a simple question could teach me so much about elixir. Thanks a ton
1 Like