Efficient way to filter a Map by value in Elixir

Viewed 9693

In Elixir, what would be an efficient way to filter a Map by its values.

Right now I have the following solution

%{foo: "bar", biz: nil, baz: 4}
|> Enum.reject(fn {_, v} -> is_nil(v) end)
|> Map.new

This solution seems pretty inefficient to me. When called on a Map, Enum.reject/2 returns a Keywords. Since I want a Map, I need to call Map.new/1 to convert that Keywords back to me.

This seems inefficient because Enum.reject/2 has to iterate over the Map once and then presumably, Map.new/1 has to iterate over the Keywords another time.

What would be a more efficient solution?

5 Answers

You can also write like this:

m = %{foo: "bar", biz: nil, baz: 4}

Enum.reduce(m, m, fn 
  {key, nil}, acc -> Map.delete(acc, key)
  {_, _}, acc -> acc
end)

The code above is quite efficient if there are few nil values in m.

Related