Elixir中的模式匹配

时间:2018-06-28 21:58:03

标签: elixir phoenix-framework

我得到类似这种格式的结果。

[
  ok: {:ok,
   %MyApp.Message{
     account_sid: "asdsad",
     api_version: "2010-04-01",
     body: "hi",
     direction: "outbound-api",
     from: nil,
     num_media: "0",
     num_segments: "0",
     sid: "asdsad",
     status: "accepted",
     subresource_uri: nil,
     to: "+15005550000",
   }},
  ok: {:ok,
   %MyApp.Message{
     account_sid: "asdasd",
     api_version: "2010-04-01",
     body: "hi",
     direction: "outbound-api",
     from: nil,
     num_media: "0",
     num_segments: "0",
     sid: "asdasd",
     status: "accepted",
     subresource_uri: nil,
     to: "+15005550000",
   }}
]

,我想转换为 [{account_sid,status},{account_sid,status}] 对于列表中的每个项目

我如何使用Elixir功能来做到这一点?

2 个答案:

答案 0 :(得分:2)

Elixir中的关键字实际上是{:keyword,value}的元组,因此您可以这样写:

Enum.map(result, fn {:ok, {:ok, %MyApp.Message{status: status, account_sid: sid}}} -> 
    {sid, status}
end)

答案 1 :(得分:0)

虽然@MateuszBielawski给出的答案在技术上是正确的,但我会使用Kernel.SpecialForms.for/1理解(我稍微改变了输入)以更安全的方式做到这一点:

input = [
  ok: {:ok, %{foo: :bar1, baz: 42}},
  ok: {:error, %{foo: :bar, baz: 42}},
  error: :some,
  ok: {:ok, %{foo: :bar2, boo: 42}}

for {:ok, {:ok, %{foo: foo}}} <- input, do: foo
#⇒ [:bar1, :bar2]

这种方法的优点是:

  • 更简洁
  • 它不会挂断意外的键(将它们过滤掉,请参见输入的第三行)
  • 它不会挂断意外的值(将其过滤掉,请参见输入的第二行)
  • 它允许即时进行其他过滤和/或更改迭代数据(请参阅链接的文档)。