Charlie Davies
Charlie Davies

Reputation: 1834

Build a new hash, by iterating over a nested hash

So i am trying to re-organise some data from the Google Places API, currently it comes out of their API like this:

{"results"=> [
             {"geometry"=>{"location"=>{"lat"=>51.503815, "lng"=>-0.11007}}, "icon"=>"http://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png", "id"=>"5f212d158f4181db3ac0619fb3c52f36d4e276c2", "name"=>"Madeira Cafe", "reference"=>"CnRjAAAApaZWmTl5wOMtW49q3D1BLKAJ_M8lmZxaD6_-AU92qWfVZdokfTWOzlp5En_r9hSUHx-EeP71hzH7iDPYAGPtiqEAXvT4WcI3xlc5XUivenbQLw0j5MHW-ErL-Hbk4xB_by0OSsXCz9etNgkjbp0QCRIQ82Dgj-I3DAJqr7I3EwsFEhoUm2RXf2rCFlSuhfKjSsPuWKA2VGA",     {"results"=> [{"geometry"=>{"location"=>{"lat"=>51.503815, "lng"=>-0.11007}},
              "icon"=>"http://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
              "id"=>"11111111",
              "name"=>"Madeira Cafe",
              "reference"=>"xxxxx",
              "types"=>["restaurant", "food", "establishment"],
              "vicinity"=>"London"}]}

The results get put into a hash with one key value - "results"

The rest of the data is the nested inside (i think) with "geometry" being the first of each record.

What I am trying to get to is a neat Hash that has one ID per place, with Lat / Lng and Name stored... so it can be stored and queried.

I have tried something like this:

results_hash = {}
result.each do |geometry, location, id|
  results_hash[id] = geometry
end

p results_hash  

but I can't get it to work... it always outputs nil or just the same hash?

I hope this makes sense, as usual if someone just says "read this" its still a great help.

Thanks!

Charlie

Upvotes: 2

Views: 4926

Answers (3)

Michael Kohl
Michael Kohl

Reputation: 66837

Sounds like you want this:

results_hash = result["results"].inject({}) { |h, res| h[res["id"]] = res["geometry"]; h }

This gives you the following hash (printed with awesome_print):

{
    "2d48a3306535b60663645323cdf972c320da8b9d" => {
        "location" => {
            "lng" => -0.114522,
            "lat" => 51.502653
        }
    },
    "5f212d158f4181db3ac0619fb3c52f36d4e276c2" => {
        "location" => {
            "lng" => -0.11007,
            "lat" => 51.503815
        }
    }
}

You'd probably want to format it slightly nicer:

results_hash = result["results"].inject({}) do |h, res| 
  h[res["id"]] = res["geometry"]
  h
end

Or if you are using 1.9:

results_hash = result["results"].each_with_object({}) do |res, h| 
  h[res["id"]] = res["geometry"]
end

Upvotes: 4

BaronVonBraun
BaronVonBraun

Reputation: 4293

If you want a hash of places with an ID pointing at lat, lon, and name, you could do something like this:

result_hash = {}
hash_from_google["results"].each do |result|
  result_hash[result["id"]] = {
    :name => result["name"], 
    :latitude => result["geometry"]["location"]["lat"],
    :longitude => result["geometry"]["location"]["lng"]
  }
end

Now you'll have a result that looks something like this:

result_hash["5f212..."] => {:name => "Madeira Cafe", :latitude => 51...., :longitude => -0.1....}

Essentially, just parse out what you need from the hash you get from the Google Places API. If you're having issues figuring out how the data is set up or anything like that, try copying it into IRB and playing around with it - doing something like that makes it very easy to figure out the structure of the hash.

Upvotes: 0

mbreining
mbreining

Reputation: 7809

What you have is an array of hashes, i.e. [{:geometry => ..., :id => ...}, {:geometry => ..., :id => ...}, etc]. I would extract the array, then iterate over each element in the array (i.e. each element in the array is a hash) using the Enumerable#inject method and build a new hash as you go.

Something to the extent of:

# locations_array is [{"geometry"=>..., "icon"=>..., "id"=>..., etc}, {"geometry"=>..., "icon"=>..., "id"=>..., etc}, etc]
results_hash = locations_array.inject({}) do |hash, element|
  # extract the id key and the long/lat values
  # store them in the new hash
  hash[element[:id]] = element[:geometry]
  hash
end

Upvotes: 0

Related Questions