Efficient way to filter a Map by value in Elixir

后端 未结 4 865
情深已故
情深已故 2021-01-04 14:20

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: ni         


        
4条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-04 15:05

    You can use :maps.filter/2, which filters a map and does not create any intermediate list:

    iex(1)> :maps.filter fn _, v -> v != nil end, %{foo: "bar", biz: nil, baz: 4}
    %{baz: 4, foo: "bar"}
    

    A simple benchmark confirms this is faster than Enum.filter + Map.new:

    map = for i <- 1..100000, into: %{}, do: {i, Enum.random([nil, 1, 2])}
    
    IO.inspect :timer.tc(fn ->
      map
      |> Enum.reject(fn {_, v} -> is_nil(v) end)
      |> Map.new
    end)
    
    IO.inspect :timer.tc(fn ->
      :maps.filter fn _, v -> v != nil end, map
    end)
    
    {44728,
     %{48585 => 1, 60829 => 2, 12995 => 1, 462 => 2, 704 => 2, 28954 => 2,
       29635 => 2, 78798 => 1, 92572 => 1, 89750 => 2, 39389 => 2, 62855 => 2,
       79313 => 1, 92062 => 2, 61871 => 1, 92856 => 2, 75920 => 1, 59922 => 1,
       37912 => 2, 30420 => 2, 51211 => 2, 7994 => 2, 78269 => 2, 9765 => 2,
       38352 => 2, 6653 => 1, 82555 => 2, 54031 => 2, 45138 => 1, 41351 => 1,
       40746 => 1, 5961 => 1, 66704 => 2, 33823 => 1, 47603 => 1, 86873 => 1,
       81009 => 2, 96255 => 1, 36219 => 1, 1328 => 2, 33314 => 1, 54477 => 2,
       40189 => 2, 27028 => 1, 31676 => 1, 94037 => 1, 32388 => 1, 4351 => 1,
       46309 => 1, ...}}
    {28638,
     %{48585 => 1, 60829 => 2, 12995 => 1, 462 => 2, 704 => 2, 28954 => 2,
       29635 => 2, 78798 => 1, 92572 => 1, 89750 => 2, 39389 => 2, 62855 => 2,
       79313 => 1, 92062 => 2, 61871 => 1, 92856 => 2, 75920 => 1, 59922 => 1,
       37912 => 2, 30420 => 2, 51211 => 2, 7994 => 2, 78269 => 2, 9765 => 2,
       38352 => 2, 6653 => 1, 82555 => 2, 54031 => 2, 45138 => 1, 41351 => 1,
       40746 => 1, 5961 => 1, 66704 => 2, 33823 => 1, 47603 => 1, 86873 => 1,
       81009 => 2, 96255 => 1, 36219 => 1, 1328 => 2, 33314 => 1, 54477 => 2,
       40189 => 2, 27028 => 1, 31676 => 1, 94037 => 1, 32388 => 1, 4351 => 1,
       46309 => 1, ...}}
    

提交回复
热议问题