dictionary - 在 Elixir 中按值过滤 Map 的有效方法

标签 dictionary filter elixir

在 Elixir 中,过滤 Map 的有效方法是什么?以其值(value)观。

现在我有以下解决方案

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

这个解决方案对我来说似乎效率很低。在 Map 上调用时, Enum.reject/2返回 Keywords .因为我想要一个 Map , 我需要调用Map.new/1转换 Keywords回到我的身边。

这似乎效率低下,因为 Enum.reject/2必须遍历 Map一次,然后大概,Map.new/1必须遍历 Keywords下一次。

什么是更有效的解决方案?

最佳答案

您可以使用 :maps.filter/2 ,它过滤 map 并且不创建任何中间列表:

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

一个简单的基准测试证实这比 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, ...}}

关于dictionary - 在 Elixir 中按值过滤 Map 的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44145893/

相关文章:

python - 当键相同时,CSV 中的特定行作为字典和逻辑 - Python

python - Pandas 数据框到字典的稀疏字典

html - mix-blend-mode multiply 在 FF 和 Chrome 中的工作方式不同

Elixir - 将 float 转换为字符串

elixir - 如何在 Elixir 或 Phoenix 框架中安排代码每隔几个小时运行一次?

c++ - 如何正确删除指针映射作为键?

JSON 数据摄取和排序以实现高效搜索

c++ - 如何在 directshow 中分割音频或编写 demuxer 过滤器?

javascript - Django 模板过滤器 - 一行

operators - 这些运算符在 Elixir 中是什么意思? ~>>,<<~