3
votes

So my goal is to take a list of maps, such as:

[%{"ts" => 1365111111, "url" => "http://example1.com"}, %{"ts" => 1365111115, "url" => "http://example2.com"}]

convert the unix timestamp value for the ts key using the DateTime module and return a new collection of the maps:

[%{"ts" => #DateTime<2013-04-04 21:31:51Z>, "url" => "http://example1.com"},%{"ts" => #DateTime<2013-04-04 21:31:51Z>, "url" => "http://example2.com"}]

So I tried using get_and_update/3 like this:

merge_maps =  [%{"ts" => 1365111111, "url" => "http://example1.com"}, %{"ts" => 1365111115, "url" => "http://example2.com"}]

new_maps = Enum.map(merge_maps, fn elem ->
  Map.get_and_update!(elem, "ts", fn curr_value ->
    {curr_value, curr_value |> DateTime.from_unix!} end)
end)

How can I return the list of modified maps in new_maps instead of what is currently returned which is a list of tuples:

[       
  {1365111111,
   %{"ts" => #DateTime<2013-04-04 21:31:51Z>, "url" => "http://mandrill.com"}},
  {1365111111, %{"ts" => #DateTime<2013-04-04 21:31:51Z>}}
]
1

1 Answers

8
votes

What you need here is Map.update!/3, not Map.get_and_update/3:

new_maps = Enum.map(merge_maps, fn elem ->
  Map.update!(elem, "ts", fn curr_value -> curr_value |> DateTime.from_unix! end)
end)

or just

new_maps = Enum.map(merge_maps, fn elem ->
  Map.update!(elem, "ts", &DateTime.from_unix!/1)
end)