I am new to Elixir and functional programming in general. What I want is to update a value for a specific key in a map and then merge that map with another.
Here is my initial map:
%{
"_id" => "exampleaaaaaaaaaaaaaaaaaaaaaaaaa",
"event" => "click",
"ip" => "127.0.0.1",
"location" => %{
"city" => "Oklahoma City",
"country" => "United States",
"country_short" => "US",
"latitude" => 35.4675598145,
"longitude" => -97.5164337158,
"postal_code" => "73101",
"region" => "Oklahoma",
"timezone" => "-05:00"
},
"msg" => %{
"_id" => "exampleaaaaaaaaaaaaaaaaaaaaaaaaa",
"_version" => "exampleaaaaaaaaaaaaaaa",
"clicks" => [%{"ts" => 1365111111, "url" => "http://mandrill.com"}],
"email" => "[email protected]",
"metadata" => %{"user_id" => 111},
"opens" => [%{"ts" => 1365111111}],
"sender" => "[email protected]",
"state" => "sent",
"subject" => "This an example webhook message",
"tags" => ["webhook-example"],
"ts" => 1365109999
},
"ts" => 1519061856,
"url" => "http://mandrill.com",
"user_agent" => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.8) Gecko/20100317 Postbox/1.1.3",
"user_agent_parsed" => %{
"mobile" => false,
"os_company" => "Apple Computer, Inc.",
"os_company_url" => "http://www.apple.com/",
"os_family" => "OS X",
"os_icon" => "http://cdn.mandrill.com/img/email-client-icons/macosx.png",
"os_name" => "OS X 10.6 Snow Leopard",
"os_url" => "http://www.apple.com/osx/",
"type" => "Email Client",
"ua_company" => "Postbox, Inc.",
"ua_company_url" => "http://www.postbox-inc.com/",
"ua_family" => "Postbox",
"ua_icon" => "http://cdn.mandrill.com/img/email-client-icons/postbox.png",
"ua_name" => "Postbox 1.1.3",
"ua_url" => "http://www.postbox-inc.com/",
"ua_version" => "1.1.3"
}
}
I have this code that's working fine:
merge_maps = get_in_attempt(
payload, ["msg", "clicks"]
) ++ get_in_attempt(
payload, ["msg", "opens"]
)
main_map = %{
"ip" => get_in(payload, ["ip"]),
"city" => get_in(payload, ["location", "city"]),
"user_agent" => get_in(payload, ["user_agent"]),
"event_type" => get_in(payload, ["event"])
}
new_maps = Enum.map(merge_maps, fn elem ->
Map.update!(elem, "ts", &DateTime.from_unix!/1)
end)
|> Enum.map(fn elem ->
Map.merge(elem, main_map)
end)
The output of new_maps:
[
%{
"city" => "Oklahoma City",
"event_type" => "click",
"ip" => "127.0.0.1",
"ts" => #DateTime<2013-04-04 21:31:51Z>,
"url" => "http://mandrill.com",
"user_agent" => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.8) Gecko/20100317 Postbox/1.1.3"
},
%{
"city" => "Oklahoma City",
"event_type" => "click",
"ip" => "127.0.0.1",
"ts" => #DateTime<2013-04-04 21:31:51Z>,
"user_agent" => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.8) Gecko/20100317 Postbox/1.1.3"
}
]
I feel like it's an overkill to enumerate twice over the list of maps but maybe that's a "good" way to achieve it considering the immutability aspect of functional programming.
Is this "best practice"?