I'm trying to work with the Google Maps geocoding API in Elixir though I'm a bit new to the language so working with nested data structures is eluding me.
I'm using HTTPotion to fetch the JSON from the geocoding endpoint and parsing it into Elixir data structures (a series of nested lists and tuples) using JSEX.
defmodule Geocode do
def fetch do
HTTPotion.start
result = HTTPotion.get "http://maps.googleapis.com/maps/api/geocode/json?address=Fairfax,%20Vermont&sensor=false"
json = JSEX.decode result.body
end
end
The following is now assigned to json.
{:ok, [{"results", [[{"address_components", [[{"long_name", "Fairfax"}, {"short_name", "Fairfax"}, {"types", ["locality", "political"]}], [{"long_name", "Franklin"}, {"short_name", "Franklin"}, {"types", ["administrative_area_level_2", "political"]}], [{"long_name", "Vermont"}, {"short_name", "VT"}, {"types", ["administrative_area_level_1", "political"]}], [{"long_name", "United States"}, {"short_name", "US"}, {"types", ["country", "political"]}]]}, {"formatted_address", "Fairfax, VT, USA"}, {"geometry", [{"bounds", [{"northeast", [{"lat", 44.772892}, {"lng", -72.92268890000001}]}, {"southwest", [{"lat", 44.6330508}, {"lng", -73.08477409999999}]}]}, {"location", [{"lat", 44.6654963}, {"lng", -73.01032}]}, {"location_type", "APPROXIMATE"}, {"viewport", [{"northeast", [{"lat", 44.772892}, {"lng", -72.92268890000001}]}, {"southwest", [{"lat", 44.6330508}, {"lng", -73.08477409999999}]}]}]}, {"types", ["locality", "political"]}]]}, {"status", "OK"}]}
I'd like to extract the latitude and the longitude from this nested data structure. I've tried using pattern matching but as the structure is fairly complex the corresponding pattern is a bit of a nightmare. While the following works it can't possibly be a good solution.
{_, [{_, [[_, _, { _, [{_, [{_, [{_, lat}, {_, lgn}]}, _]}, _, _, _] }, _]]}, _]} = json
So my question is what is the best way to extract values from deeply nested data structures in Elixir? Any solutions or nudges in the right direction would be greatly appreciated.
Check out the source to Seth Falcon's ej library:
https://github.com/seth/ej
It does more or less what you're wanting to do, using recursion.
I'm not an Elixir expert, but you might be able to just use that library directly.
The ej library looks like a good choice, but in addition I might cut to the heart of the data structure right away:
{:ok, [{"results", results}, {"status", status}]} = JSEX.decode result.body
or if you will always only use the first result:
{:ok, [{"results", [geo_json | _]}, {"status", status}]} = JSEX.decode result.body
Then I would use the ej library on the geo_json data structure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With