0

I have a JSON array:

response = [
  %{
    "created_at" => 1542757526,
    "email" => "bcs@yahoo.com",
    "first_name" => "rana",
    "id" => "YW1pcnBheWFyeUB5YWhvby5jb20=",
    "last_clicked" => nil,
    "last_emailed" => nil,
    "last_name" => "amir",
    "last_opened" => nil,
    "updated_at" => 1542759123
  },
  %{
    "created_at" => 1542757457,
    "email" => "abc@gmail.com",
    "first_name" => "rana",
    "id" => "cmFtaXIyNDI2QGdtYWlsLmNvbQ==",
    "last_clicked" => nil,
    "last_emailed" => nil,
    "last_name" => "amir",
    "last_opened" => nil,
    "updated_at" => 1542759001
  },
  # .......
]

I'm trying to get the email field of all items in the response variable. Example:

["bcs@yahoo.com", "xyz@gmail.com", ....]
Sheharyar
  • 73,588
  • 21
  • 168
  • 215
Rana. Amir
  • 187
  • 3
  • 15
  • Can you show any code that you have tried? What part of your code is having the problem? – Justin Wood Nov 26 '18 at 20:26
  • yeah when I tired `Enum.flat_map(response, fn(c) -> c["email"] end)` getting this error: `(Protocol.UndefinedError) protocol Enumerable not implemented for "bcs@yahoo.com". This protocol is implemented for: DBConnection.PrepareStream, DBConnection.Stream, Date.Range, Ecto.Adapters.SQL.Stream, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, List, Map, MapSet, Postgrex.Stream, Range, Stream, Timex.Interval` – Rana. Amir Nov 26 '18 at 20:28

2 Answers2

2

You're looking for Enum.map/2. This method calls the passed function on every item in the given list/enumerable:

Enum.map(response, fn item -> item["email"] end )

Alternatively, you can use the shorthand and make it concise:

Enum.map(response, &(&1["email"]))

External Resources: See this and also this to understand the concept of mapping in functional programming in general.

Side note: flat_map/2 is a variation of map/2 that expects the "mapped result" to be another list (so it can be joined and flattened with the rest of the mapped results).

Sheharyar
  • 73,588
  • 21
  • 168
  • 215
0

In addition to map, you could also look at comprehensions. Essentially they combine the functionality of Enum.map/2 & Enum.filter/2.

They allow you to do something like this:

for %{"email" => email} <- response, do: email

or this:

for item <- response, do: item["email"]

Note there's a subtle difference in behavior between the result of the two: the former will filter out any items that do not match the left-hand side (it will only keep maps with an "email" key), but the latter will map the items lacking an email to nil.

Brett Beatty
  • 5,690
  • 1
  • 23
  • 37