使用捕获运算符时如何不使用所有参数?

时间:2016-11-26 09:53:50

标签: elixir

我试图了解捕获操作符以及它可以在哪里使用。这是一个有效的例子:

%{name: "Daniel", dob: 2016, email: "daniel@gmail.com"}
|> Enum.filter(fn({_k, v}) -> is_binary(v) end)
|> Enum.into(%{})

返回

  

%{email:" daniel@gmail.com" ;,姓名:" Daniel"}。

现在我试图在Enum.filter / 2中使用捕获运算符,我在那里使用地图对中的第二个元素。

%{name: "Daniel", dob: 2016, email: "daniel@gmail.com"}
|> Enum.filter(&is_binary(&2))
|> Enum.into(%{})

和iex控制台说

** (CompileError) iex:2: capture &2 cannot be defined without &1
    (elixir) src/elixir_fn.erl:118: :elixir_fn.do_capture/4
    (elixir) expanding macro: Kernel.|>/2
             iex:2: (file)

结果有些预期。我的问题是如何绕过这个,如何在不使用第一个元素的情况下使用第二个元素作为参数?

1 个答案:

答案 0 :(得分:1)

与错误消息一样,您不能仅使用捕获运算符使用第二个参数,但是,函数fn({_k, v}) -> is_binary(v) end只接受一个参数,这是一个2元素元组,而不是2个参数。如果您不想为其命名,可以使用elem/2

iex(1)> %{name: "Daniel", dob: 2016, email: "daniel@gmail.com"} |>
...(1)> Enum.filter(&is_binary(elem(&1, 1))) |>
...(1)> Enum.into(%{})
%{email: "daniel@gmail.com", name: "Daniel"}

对于此特定用例,您还可以使用:maps.filter/2。它比原始代码短,可能效率更高:

iex(2)> :maps.filter fn k, v -> is_binary(v) end, %{name: "Daniel", dob: 2016, email: "daniel@gmail.com"}
%{email: "daniel@gmail.com", name: "Daniel"}