0
votes

I have a results something like this format..

[
  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",
   }}
]

and I want to convert to [ {account_sid, status}, {account_sid, status}] for eachh item in list

How can I do this using Elixir function?

2
May I ask where this output comes from? Just curious. - Aleksei Matiushkin
I am using Twilio API. results returns from Twilio API. - Tae

2 Answers

2
votes

Keywords in Elixir are in reality a tuple of {:keyword, value}, so you could write it like this:

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

While the answer given by @MateuszBielawski is technically correct, I would do it in safer way using Kernel.SpecialForms.for/1 comprehension (I altered the input a bit):

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]

Advantages of this approach are:

  • it’s more succinct
  • it won’t hang up on unexpected keys (filtering them out, see the third line of the input)
  • it won’t hang up on unexpected values (filtering them out, see the second line of the input)
  • it allows additional filtering and/or altering the iterated data on the fly (see the linked documentation).