【问题标题】:Pattern Matching in ElixirElixir 中的模式匹配
【发布时间】:2018-06-28 21:58:03
【问题描述】:

我有类似这种格式的结果..

[
  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 功能做到这一点?

【问题讨论】:

  • 请问这个输出是从哪里来的?只是好奇。
  • 我正在使用 Twilio API。结果从 Twilio API 返回。

标签: elixir phoenix-framework


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    虽然@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]
    

    这种方法的优点是:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-07
      • 2017-03-06
      • 2015-08-15
      • 2017-10-17
      • 2017-03-16
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      相关资源
      最近更新 更多