kharash markownikoff
kharash markownikoff

Reputation: 23

Transform a list of maps in Elixir

I have a list of maps, that I get from querying my database.It has a datetime field that I want to transform into another list of maps where the datetime field is transformed to it's corresponding epoch value.

What i have:

[
  %{
    m_id: 267,
    end: #DateTime<2020-03-07 17:30:00Z>,
    start: #DateTime<2020-03-07 14:30:00Z>,
    type: "normal",
    s_name: "smum",
    w_id: 256
  },
  %{
    m_id: 267,
    end: #DateTime<2020-03-07 07:30:00Z>,
    start: #DateTime<2020-03-07 04:30:00Z>,
    type: "normal",
    s_name: "smum",
    w_id: 256
  }
]

What i want to transform it to:

[
  %{
    m_id: 267,
    end: 12356789, #some epoch value for eg
    start: 12367576, #some epoch value for eg
    type: "normal",
    s_name: "smum",
    w_id: 256
  },
  %{
    m_id: 267,
    end: 12334567, #some epoch value for eg
    start: 12354767, #some epoch value for eg
    type: "normal",
    s_name: "smum",
    w_id: 256
  }
]

Upvotes: 0

Views: 148

Answers (2)

Alexey Romanov
Alexey Romanov

Reputation: 170713

To transform a single map, you can do

%{map | end: DateTime.to_unix(map.end), start: DateTime.to_unix(map.start) }

So just Enum.map over the list to apply this to all list members:

Enum.map(list, fn map -> %{map | end: DateTime.to_unix(map.end), start: DateTime.to_unix(map.start) } end)

(I suspected there may be a problem using the map update syntax here because end is a reserved word, but I tested in https://www.jdoodle.com/execute-elixir-online/ and it works.)

Upvotes: 5

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

I would go with Kernel.SpecialForms.for/1 comprehension.

for %{start: s, end: e} = map <- list do
  %{map | start: DateTime.to_unix(s), end: DateTime.to_unix(e)}
end

It’s slightly different from Enum.map/2 solution, because it would discard those elements not having either start or end keys. To handle those properly, one should use Map.update/4 wisely.

Upvotes: 2

Related Questions