3
$\begingroup$

I'm have some trouble formatting the Output of a 'Import' request. I get this as a return of a google places API request:

out={"html_attributions" -> {}, 
    "results" -> {{"geometry" -> {"location" -> {"lat" -> 48.35593, 
    "lng" -> 10.89459}}, 
    "id" -> "4f8d22dd53bf7c6eb79360a324ce616999b82b5f", 
    "place_id" -> "ChIJA7PvOkG9nkcRmJkimVDMQQ4", 
    "reference" -> 
    "CmRcAAAAdwzUsk-\
     DX8sUI1HMyFVujZ2gu8claGrxhJ8ZVj80rBBEkbiiLtQnqCalgnOvIMkHF17f5TzkB6hXc\
     STLG36HPB_KU08JczxpHSIpc1Z4UlKqhTHXTShYTKimqxowUsUBEhBRY_fMjrk_\
     UIiaZ9U1MMPsGhQPwm98QfAw74FogeUryqxPxGMv8g"}, {"geometry" -> \
     {"location" -> {"lat" -> 48.3747, "lng" -> 10.8957}}, 
     "id" -> "6d4568d42a2011543410ab2d0d805b521562a237", 
     "place_id" -> "ChIJBzM8CmgenEcRqrj1bDQ6WDY", 
     "reference" -> 
     "CmRZAAAAqcP7N7Cv35I_HLTMKiuYajWRh6qFNadB_\
      trryO8EgtOYhyz2Wjfq7sYaKAwXKU_5HLq4tB1tS5_f4QZNDeM_\
      lUEd8XI74DNz5CntTTbGIdOPs0hYsb6MOvitVUBT1PaoEhCo3qnHXZYwLyX8vhRapm9LGh\
      QzEWMmVxnp1wpetlGDMlp_OC55QQ"}}, "status" -> "OK"}

by trial and error I found a way to get the location of the first place:

out[[2, 2]][[1, 1]][[2, 1]]

"location" -> {"lat" -> 48.35593, "lng" -> 10.895}

the second place is

out[[2, 2]][[2, 1]][[2, 1]]

"location" -> {"lat" -> 48.3747, "lng" -> 10.8957}

the number of places is

Length[out[[2, 2]]]

2

For longer outputs I'd like to get all locations automatically. My naive approach was

[[2, 2]][[#, 1]][[2, 1]]&/@out

but that does not work.

How can I get a structured output of all the location data from this JSON output?

I'm also looking for general advice how to best handle google places and JSON output.

Perhaps someone even knows a nice way to autmatically display the geodata on a map in mathematica.

Please provide a mathematica9 answer as I only have this version. But I might buy v10 soon so I'm also interested in the new v10 features :)

$\endgroup$
  • $\begingroup$ [[2, 2]][[#, 1]][[2, 1]]&/@out is simply not correct syntax. Did part of that line get removed when you pasted it? $\endgroup$ – Szabolcs Jun 16 '15 at 8:09
7
$\begingroup$

With Mathematica 10 or later, I recommend converting this data structure to either an Association or a Dataset:

asc = Replace[out, r : {__Rule} :> Association[r], {0, Infinity}];

ds = Dataset[asc]

Then you can index it with the keys, e.g.

asc[["results", 1, "geometry"]]
(* <|"location" -> <|"lat" -> 48.35593, "lng" -> 10.89459|>|> *)

asc[["results", 1, "geometry", "location", "lat"]]
(* 48.35593 *)

Note: the difference between asc[[ ... ]] and asc[ ... ] is that the latter doesn't allow for numerically indexed parts, only for keys.


With Mathematica 9 or earlier, we can use /. to extract parts of rule lists. For example, to get "a" from rules = {"a" -> 1, "b" -> 2}, we can use

"a" /. rules

Starting from this idea and the observation that JSON dictionaries use strings as keys, we can write a simple part extractor:

jsonPart[data_, part_String] := part /. data (* for rule lists *)
jsonPart[data_, part_Integer] := data[[part]] (* for arrays *)

jsonPart[data_, partList_List] := Fold[jsonPart, data, partList] (* multiple part specifications *)

Then:

jsonPart[out, {"results", 1, "geometry"}]
(* {"location" -> {"lat" -> 48.35593, "lng" -> 10.89459}} *)

jsonPart[out, {"results", 1, "geometry", "location", "lat"}]
(* 48.35593 *)

This is meant only as a simple example, without error checking. If you are going to use this several times, it's probably a good idea to implement some error checking as well (make sure that the dictionary key is actually in the list before attempting to extract it).

$\endgroup$
  • $\begingroup$ Association is a mathematica10 feature, isn't it? I only have v9 :( $\endgroup$ – spore234 Jun 16 '15 at 8:17
  • $\begingroup$ @spore234 Please update the question and mention this. $\endgroup$ – Szabolcs Jun 16 '15 at 8:18
  • $\begingroup$ @spore234 I updated the answer. $\endgroup$ – Szabolcs Jun 16 '15 at 8:24
2
$\begingroup$

I like to use Cases with HoldPattern for these types of structures:

Cases[out, HoldPattern["location" -> latlon_] :> {latlon[[1, 2]], latlon[[2, 2]]}, Infinity]

{{48.3559, 10.8946}, {48.3747, 10.8957}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.