Ruby parse csv to usable hash - ruby

I'm making a graph of NBA team payrolls. I have this csv: http://www.basketball-reference.com/contracts/
Rk,Team,2016-17,2017-18,2018-19,2019-20,2020-21,2021-22
1,Cleveland Cavaliers,$123590274,$118585590,$111958508,$65464580,,
2,Los Angeles Clippers,$118663837,$111415942,$59741545,$2500725,,
3,Portland Trail Blazers,$115817639,$138409348,$121862764,$118747593,$62965110,
4,Dallas Mavericks,$112488859,$94965622,$62766454,$35361887,,
5,Memphis Grizzlies,$114096737,$97742075,$88773581,$86212960,$34504132,
6,San Antonio Spurs,$110631827,$96744068,$56909494,$25990334,,
7,Detroit Pistons,$110492645,$103423474,$97903566,$62944822,$28751775,
8,Orlando Magic,$110283846,$74591158,$60217493,$43122365,$17000000,
9,Toronto Raptors,$109253824,$102105184,$84967199,$51464677,$27739975,
10,Washington Wizards,$107257619,$99510391,$103018516,$49454077,$28751775,
11,Miami Heat,$105296376,$95803765,$94126541,$65558388,,
12,Golden State Warriors,$104677735,$66269011,$40907537,$20844187,,
13,New York Knicks,$104501658,$77290233,$78325386,$41195895,,
14,Milwaukee Bucks,$103338094,$112928334,$89209363,$76367783,$29393637,$1865547
15,Los Angeles Lakers,$102354756,$84416158,$62677311,$56232985,,
16,New Orleans Pelicans,$102177578,$78434268,$67966414,$65355463,$28751775,
17,Charlotte Hornets,$101879187,$91900885,$74203714,$53571467,$27130434,
18,Atlanta Hawks,$101793777,$70277529,$46071092,$25355630,,
19,Sacramento Kings,$99168232,$84890581,$27219195,$8350732,,
20,Houston Rockets,$97639130,$97370875,$73164132,$68025858,,
21,Chicago Bulls,$96908430,$81438211,$42663896,$24345313,,
22,Oklahoma City Thunder,$96181060,$68581249,$68960837,$8863055,,
23,Boston Celtics,$95289212,$77610987,$50413474,$45792877,,
24,Indiana Pacers,$91950761,$80519787,$62913923,,,
25,Minnesota Timberwolves,$84638527,$68085957,$37620814,$5348007,,
26,Utah Jazz,$84386693,$71138358,$17001288,,,
27,Phoenix Suns,$84297090,$71123131,$66028579,$26744625,,
28,Denver Nuggets,$79627212,$81852764,$49452791,$10497490,,
29,Brooklyn Nets,$78769729,$60910873,$25603813,$9344638,,
30,Philadelphia 76ers,$75336267,$50155264,$26385506,$14125600,,
In ruby I wrote:
def payrolls
payrolls = {}
CSV.foreach("payrolls.csv", :headers => true, :header_converters => :symbol, :converters => :all) do |row|
payrolls[row.fields[1]] = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
end
puts payrolls.inspect
end
Which outputs:
{
"Cleveland Cavaliers"=>{:team=>"Cleveland Cavaliers", :"201617"=>"$123590274", :"201718"=>"$118585590", :"201819"=>"$111958508", :"201920"=>"$65464580", :"202021"=>nil, :"202122"=>nil},
"Los Angeles Clippers"=>{:team=>"Los Angeles Clippers", :"201617"=>"$118663837", :"201718"=>"$111415942", :"201819"=>"$59741545", :"201920"=>"$2500725", :"202021"=>nil, :"202122"=>nil
}
Which is fairly usable. However, since the years heading is a number, when I use
payrolls[Cleveland Cavaliers][:201617]
I'm getting this error:
payrolls.rb:31: syntax error, unexpected tINTEGER, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
puts payrolls["Cleveland Cavaliers"][:201617]
Thus, what is the best way to get the salary data for the graph?

Your code has a syntax error which I fixed: you didn't have the second to last }:
hash = {
"Cleveland Cavaliers"=>{:team=>"Cleveland Cavaliers", :"201617"=>"$123590274", :"201718"=>"$118585590", :"201819"=>"$111958508", :"201920"=>"$65464580", :"202021"=>nil, :"202122"=>nil},
"Los Angeles Clippers"=>{:team=>"Los Angeles Clippers", :"201617"=>"$118663837", :"201718"=>"$111415942", :"201819"=>"$59741545", :"201920"=>"$2500725", :"202021"=>nil, :"202122"=>nil}
}
You should access the hash by the key. Neither Cleveland Cavaliers nor :201617 are valid objects, thus you get the error.
The key you are looking at is :"201617":
hash["Cleveland Cavaliers"][:"201617"]
#=> "$123590274"

Use a string instead of a symbol:
payrolls["Cleveland Cavaliers"]["201617"]

Related

How can i separate a full name?

I've to take the right part and clean it after it comparate with the middle part and save if are equal
> #!/usr/bin/env ruby
require 'rubygems'
require 'levenshtein'
require 'csv'
# Extending String class for blank? method
class String
def blank?
self.strip.empty?
end
end
# In
lines = CSV.read('entrada.csv')
lines.each do |line|
id = line[0].upcase.strip
left = line[1].upcase.strip
right = line[2].upcase.strip
eduardo = line[2].upcase.split(' ','de')
line[0] = id
line[1] = left
line[2] = right
line[4] = eduardo[0]+eduardo[1]
distance = Levenshtein.distance left, right
line << 99 if (left.blank? or right.blank?)
line << distance unless (left.blank? or right.blank?)
end
# Out
# counter = 0
CSV.open('salida.csv', 'w') do |csv|
lines.each do |line|
# counter = counter + 1 if line[3] <= 3
csv << line
end
end
# p counter
The middle is the correct the rigth i should correct
Some examples:
Eduardo | Abner | Herrera | Herrera -> Eduardo Herrera
Angel | De | Leon -> Angel De Leon
Maira | Angelina | de | Leon -> Maira De Leon
Marquilla | Gutierrez | Petronilda |De | Leon -> Marquilla Petronilda
First order of business is to come up with some rules. Based on your examples, and Spanish naming customs, here's my stab at the rules.
A name has a forename, paternal surname, and optional maternal surname.
A forename can be multiple words.
A surname can be multiple words linked by a de, y, or e.
So ['Marquilla', 'Gutierrez', 'Petronilda', 'De', 'Leon'] should be { forename: 'Marquilla', paternal_surname: 'Gutierrez', maternal_surname: 'Petronilda de Leon' }
To simplify the process, I'd first join any composite surnames into one field. ['Marquilla', 'Gutierrez', 'Petronilda', 'De', 'Leon'] becomes ['Marquilla', 'Gutierrez', 'Petronilda De Leon']. Watch out for cases like ['Angel', 'De', 'Leon'] in which case the surname is probably De Leon.
Once that's done, figuring out which part is which becomes easier.
name = {}
if parts.length == 1
error?
# The special case of only two parts: forename paternal_surname
elsif parts.length == 2
name = {
forename: parts[0],
paternal_surname: parts[1]
}
# forename paternal_surname maternal_surname
else
# The forename can have multiple parts, so work from the
# end and whatever's left is their forename.
name[:maternal_surname] = parts.pop
name[:paternal_surname] = parts.pop
name[:forename] = parts.join(" ")
end
There's a lot of ambiguity in Spanish naming, so this can only be an educated guess at what their actual name is. You'll probably have to tweak the rules as you learn more about the dataset. For example, I'm pretty sure handling of de is not that simple. For example...
One Leocadia Blanco Álvarez, married to a Pedro Pérez Montilla, may be addressed as Leocadia Blanco de Pérez or as Leocadia Blanco Álvarez de Pérez
In that case ['Marquilla', 'Gutierrez', 'Petronilda', 'De', 'Leon'] becomes ['Marquilla', 'Gutierrez', 'Petronilda', 'De Leon'] which is { forename: 'Marquilla', paternal_surname: 'Gutierrez', maternal_surname: 'Petronilda', married_to: 'Leon' } or 'Marquilla Gutierrez Petronilda who is married to someone whose parental surname is Leon.
Good luck.
I would add more columns to the database, like last_name1, last_name2, last_name3, etc, and make them optional (don't put validations on those attributes). Hope that answers your question!

How do I drill down into a JSON object using Ruby's JSON gem

I have some JSON returned from Google Maps API.
{"results"=>
[{"address_components"=>
[{"long_name"=>"1600", "short_name"=>"1600", "types"=>["street_number"]},
{"long_name"=>"President's Park",
"short_name"=>"President's Park",
"types"=>["establishment"]},
{"long_name"=>"Pennsylvania Avenue Northwest",
"short_name"=>"Pennsylvania Ave NW",
"types"=>["route"]},
{"long_name"=>"Washington",
"short_name"=>"Washington",
"types"=>["locality", "political"]},
{"long_name"=>"District of Columbia",
"short_name"=>"DC",
"types"=>["administrative_area_level_1", "political"]},
{"long_name"=>"United States",
"short_name"=>"US",
"types"=>["country", "political"]},
{"long_name"=>"20500", "short_name"=>"20500", "types"=>["postal_code"]}],
"formatted_address"=>
"1600 Pennsylvania Avenue Northwest, President's Park, Washington, DC 20500, USA",
"geometry"=>
{"location"=>{"lat"=>38.8977332, "lng"=>-77.0365305},
"location_type"=>"ROOFTOP",
"viewport"=>
{"northeast"=>{"lat"=>38.8990821802915, "lng"=>-77.0351815197085},
"southwest"=>{"lat"=>38.8963842197085, "lng"=>-77.03787948029151}}},
"partial_match"=>true,
"types"=>["street_address"]}],
"status"=>"OK"}
I'm trying to access the latitude and longitude like so:
parsed = JSON.parse(data)
p parsed["results"]["location"]["lat"]
p parsed["results"]["location"]["lng"]
When I do so, my code throws and error: "no implicit conversion of String into Integer (TypeError).
I will be very grateful to anyone who can shed some light onto my problem. Thank you.
So, in your case it would be
p parsed["results"][0]["geometry"]["location"]
# => {"lat"=>38.8977332, "lng"=>-77.0365305}

How to parse a more complicated JSON object in Ruby on Sinatra

I'm a Java guy, new to Ruby. I've been playing with it just to see what it can do, and I'm running into an issue that I can't solve.
I decided to try out Sinatra, again, just to see what it can do, and decided to play with the ESPN API and see if I can pull the venue of a team via the API.
I'm able to make the call and get the data back, but I am having trouble parsing it:
{"sports"=>[{"name"=>"baseball", "id"=>1, "uid"=>"s:1", "leagues"=>[{"name"=>"Major League Baseball", "abbreviation"=>"mlb", "id"=>10, "uid"=>"s:1~l:10", "groupId"=>9, "shortName"=>"MLB", "teams"=>[{"id"=>17, "uid"=>"s:1~l:10~t:17", "location"=>"Cincinnati", "name"=>"Reds", "abbreviation"=>"CIN", "color"=>"D60042", "venues"=>[{"id"=>83, "name"=>"Great American Ball Park", "city"=>"Cincinnati", "state"=>"Ohio", "country"=>"", "capacity"=>0}], "links"=>{"api"=>{"teams"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17"}, "news"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news"}, "notes"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes"}}, "web"=>{"teams"=>{"href"=>"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public"}}, "mobile"=>{"teams"=>{"href"=>"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public"}}}}]}]}], "resultsOffset"=>0, "resultsLimit"=>50, "resultsCount"=>1, "timestamp"=>"2013-08-04T14:47:13Z", "status"=>"success"}
I want to pull the venues part of the object, specifically the name value. Every time I try to parse it I end up getting an error along the lines of "cannot change from nil to string" and then also I've gotten an integer to string error.
Here's what i have so far:
get '/venue/:team' do
id = ids[params[:team]]
url = 'http://api.espn.com/v1/sports/baseball/mlb/teams/' + id + '?enable=venues&apikey=' + $key
resp = Net::HTTP.get_response(URI.parse(url))
data = resp.body
parsed = JSON.parse(resp.body)
#venueData = parsed["sports"]
"Looking for the venue of the #{params[:team]}, which has id " + id + ", and here's the data returned: " + venueData.to_s
end
When I do parsed["sports"} I get:
[{"name"=>"baseball", "id"=>1, "uid"=>"s:1", "leagues"=>[{"name"=>"Major League Baseball", "abbreviation"=>"mlb", "id"=>10, "uid"=>"s:1~l:10", "groupId"=>9, "shortName"=>"MLB", "teams"=>[{"id"=>17, "uid"=>"s:1~l:10~t:17", "location"=>"Cincinnati", "name"=>"Reds", "abbreviation"=>"CIN", "color"=>"D60042", "venues"=>[{"id"=>83, "name"=>"Great American Ball Park", "city"=>"Cincinnati", "state"=>"Ohio", "country"=>"", "capacity"=>0}], "links"=>{"api"=>{"teams"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17"}, "news"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news"}, "notes"=>{"href"=>"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes"}}, "web"=>{"teams"=>{"href"=>"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public"}}, "mobile"=>{"teams"=>{"href"=>"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public"}}}}]}]}]
But nothing else parses. Please help!
Like I said, I'm not trying to do anything fancy, just figure out Ruby a little for fun, but I have been stuck on this issue for days now. Any help would be appreciated!
EDIT:
JSON straight from the API:
{"sports" :[{"name" :"baseball","id" :1,"uid" :"s:1","leagues" :[{"name" :"Major League Baseball","abbreviation" :"mlb","id" :10,"uid" :"s:1~l:10","groupId" :9,"shortName" :"MLB","teams" :[{"id" :17,"uid" :"s:1~l:10~t:17","location" :"Cincinnati","name" :"Reds","abbreviation" :"CIN","color" :"D60042","venues" :[{"id" :83,"name" :"Great American Ball Park","city" :"Cincinnati","state" :"Ohio","country" :"","capacity" :0}],"links" :{"api" :{"teams" :{"href" :"http://api.espn.com/v1/sports/baseball/mlb/teams/17"},"news" :{"href" :"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news"},"notes" :{"href" :"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes"}},"web" :{"teams" :{"href" :"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public"}},"mobile" :{"teams" :{"href" :"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public"}}}}]}]}],"resultsOffset" :0,"resultsLimit" :50,"resultsCount" :1,"timestamp" :"2013-08-05T19:44:32Z","status" :"success"}
The result of data.inspect:
"{\"sports\" :[{\"name\" :\"baseball\",\"id\" :1,\"uid\" :\"s:1\",\"leagues\" :[{\"name\" :\"Major League Baseball\",\"abbreviation\" :\"mlb\",\"id\" :10,\"uid\" :\"s:1~l:10\",\"groupId\" :9,\"shortName\" :\"MLB\",\"teams\" :[{\"id\" :17,\"uid\" :\"s:1~l:10~t:17\",\"location\" :\"Cincinnati\",\"name\" :\"Reds\",\"abbreviation\" :\"CIN\",\"color\" :\"D60042\",\"venues\" :[{\"id\" :83,\"name\" :\"Great American Ball Park\",\"city\" :\"Cincinnati\",\"state\" :\"Ohio\",\"country\" :\"\",\"capacity\" :0}],\"links\" :{\"api\" :{\"teams\" :{\"href\" :\"http://api.espn.com/v1/sports/baseball/mlb/teams/17\"},\"news\" :{\"href\" :\"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news\"},\"notes\" :{\"href\" :\"http://api.espn.com/v1/sports/baseball/mlb/teams/17/news/notes\"}},\"web\" :{\"teams\" :{\"href\" :\"http://espn.go.com/mlb/team/_/name/cin/cincinnati-reds?ex_cid=espnapi_public\"}},\"mobile\" :{\"teams\" :{\"href\" :\"http://m.espn.go.com/mlb/clubhouse?teamId=17&ex_cid=espnapi_public\"}}}}]}]}],\"resultsOffset\" :0,\"resultsLimit\" :50,\"resultsCount\" :1,\"timestamp\" :\"2013-08-05T19:44:24Z\",\"status\" :\"success\"}"
parsed["sports"] does not exist, parse your input and inspect it/ dump it
With the data you've provided in the question, you can get to the venues information like this:
require 'json'
json = JSON.parse data
json["sports"].first["leagues"].first["teams"].first["venues"]
# => [{"id"=>83, "name"=>"Great American Ball Park", "city"=>"Cincinnati", "state"=>"Ohio", "country"=>"", "capacity"=>0}]
By replacing each of the first calls with an iterator, you can search through without knowing where the data is:
json["sports"].each{|h|
h["leagues"].each{|h|
h["teams"].each{|h|
venues = h["venues"].map{|h| h["name"]}.join(", ")
puts %Q!name: #{h["location"]} #{h["name"]} venues: #{venues}!
}
}
}
This outputs:
name: Cincinnati Reds venues: Great American Ball Park
Depending on how stable the response data is you may be able to cut out several of the iterators:
json["sports"].first["leagues"]
.first["teams"]
.each{|h|
venues = h["venues"].map{|h| h["name"] }.join(", ")
puts %Q!name: #{h["location"]} #{h["name"]} venues: #{venues}!
}
and you'll most likely want to save the data, so something like each_with_object is helpful:
team_and_venues = json["sports"].first["leagues"]
.first["teams"]
.each_with_object([]){|h,xs|
venues = h["venues"].map{|h| h["name"]}.join(", ")
xs << %Q!name: #{h["location"]} #{h["name"]} venues: #{venues}!
}
# => ["name: Cincinnati Reds venues: Great American Ball Park"]
team_and_venues
# => ["name: Cincinnati Reds venues: Great American Ball Park"]
Notice that when an iterator declares variables, even if there is a variable with the same name outside the block, the scope of the block is respected and the block's variables remain local.
That's some pretty ugly code if you ask me, but it's a place to start.

Parsing a dictionary text file in ruby

I am using ruby to try and parse a text file that has the form...
AAB eel bbc
ABA did eye non pap mom ere bob nun eve pip gig dad nan ana gog aha
mum sis ada ava ewe pop tit gag tat bub pup
eke ele hah huh pep sos tot wow aba ala
bib dud tnt
ABB all see off too ill add lee ass err xii ann fee vii inn egg odd bee dee goo
woo cnn pee fcc tee wee ebb edd gee ott ree vee ell orr rcc att boo cee cii
coo kee moo mss soo doo faa hee icc iss itt kii loo mee nee nuu ogg opp pii
tll upp voo zee
I need to be able to search by the first column, such as "AAB",and then search through all values that are associated with that key. I have tried to import the text file into a hash of arrays but could never get more than the first value to store. I have no preference as to how I can search the file, whether that is store the data into some data structure or just search the text file every time, I just need to be able to do it. I am at a loss as to how to proceed with this and any help would be greatly appreciated. Thanks
-amc25114
This will read your dictionary file. I'm storing the content in a string, then
turning it into a StringIO object to let me pretend it's a file. You can use
File.readlines to read directly from the file itself:
require 'pp'
require 'stringio'
text = 'AAB eel bbc
ABA did eye non pap mom ere bob nun eve pip gig dad nan ana gog aha
mum sis ada ava ewe pop tit gag tat bub pup
eke ele hah huh pep sos tot wow aba ala
bib dud tnt
ABB all see off too ill add lee ass err xii ann fee vii inn egg odd bee dee goo
woo cnn pee fcc tee wee ebb edd gee ott ree vee ell orr rcc att boo cee cii
coo kee moo mss soo doo faa hee icc iss itt kii loo mee nee nuu ogg opp pii
tll upp voo zee
'
file = StringIO.new(text)
dictionary = Hash[
file.readlines.slice_before(/^\S/).map{ |ary|
key, *values = ary.map(&:strip).join(' ').split(' ')
[key, values]
}
]
dictionary is a hash looking like:
{
"AAB"=>[
"eel", "bbc"
],
"ABA"=>[
"did", "eye", "non", "pap", "mom", "ere", "bob", "nun", "eve", "pip",
"gig", "dad", "nan", "ana", "gog", "aha", "mum", "sis", "ada", "ava",
"ewe", "pop", "tit", "gag", "tat", "bub", "pup", "eke", "ele", "hah",
"huh", "pep", "sos", "tot", "wow", "aba", "ala", "bib", "dud", "tnt"
],
"ABB"=>[
"all", "see", "off", "too", "ill", "add", "lee", "ass", "err", "xii",
"ann", "fee", "vii", "inn", "egg", "odd", "bee", "dee", "goo", "woo",
"cnn", "pee", "fcc", "tee", "wee", "ebb", "edd", "gee", "ott", "ree",
"vee", "ell", "orr", "rcc", "att", "boo", "cee", "cii", "coo", "kee",
"moo", "mss", "soo", "doo", "faa", "hee", "icc", "iss", "itt", "kii",
"loo", "mee", "nee", "nuu", "ogg", "opp", "pii", "tll", "upp", "voo", "zee"
]
}
You can look up using the keys:
dictionary['AAB']
=> ["eel", "bbc"]
And search inside the array using include?:
dictionary['AAB'].include?('eel')
=> true
dictionary['AAB'].include?('foo')
=> false
class A
def initialize
#h, key = readlines.inject({}) do |m, s|
a = s.split
m[key = a.shift] = [] if s =~ /^[^\s]/
m[key] += a
m
end
end
def lookup k, v # not sure what you really want to do here
p [k, v, (#h[k].index v)]
end
self
end.new.lookup 'ABA', 'wow'
My 2 cents:
file = File.open("/path_to_file_here")
recent_key = ""
results = Hash.new
while (line = file.gets)
key = line[/[A-Z]+/]
recent_key = key if key
line.scan(/[a-z]+/).each do |val|
results[recent_key.to_sym] = [] if !results[recent_key.to_sym]
results[recent_key.to_sym] << val
end
end
puts results
This will give you this ouput:
{
:AAB=>["eel", "bbc"],
:ABA=>["did", "eye", "non", "pap", "mom", "ere", "bob", "nun", "eve", "pip", "gig", "dad", "nan", "ana", "gog", "aha", "mum", "sis", "ada", "ava", "ewe", "pop", "tit", "gag", "tat", "bub", "pup", "eke", "ele", "hah", "huh", "pep", "sos", "tot", "wow", "aba", "ala", "bib", "dud", "tnt"],
:ABB=>["all", "see", "off", "too", "ill", "add", "lee", "ass", "err", "xii", "ann", "fee", "vii", "inn", "egg", "odd", "bee", "dee", "goo", "woo", "cnn", "pee", "fcc", "tee", "wee", "ebb", "edd", "gee", "ott", "ree", "vee", "ell", "orr", "rcc", "att", "boo", "cee", "cii", "coo", "kee", "moo", "mss", "soo", "doo", "faa", "hee", "icc", "iss", "itt", "kii", "loo", "mee", "nee", "nuu", "ogg", "opp", "pii", "tll", "upp", "voo", "zee"]
}

Working with nested hashes in Rails 3

I'm working with the Koala gem and the Facebook Graph API, and I want to break down the results I get for a users feed into separate variables for inserting into a mySQL database, probably using Active Record. Here is the code I have so far:
#token = Service.where(:provider => 'facebook', :user_id => session[:user_id]).first.token
#graph = Koala::Facebook::GraphAPI.new(#token)
#feeds = params[:page] ? #graph.get_page(params[:page]) : #graph.get_connections("me", "home")
And here is what #feeds looks like:
[{"id"=>"1519989351_1799856285747", "from"=>{"name"=>"April Daggett Swayne", "id"=>"1519989351"},
"picture"=>"http://photos-d.ak.fbcdn.net/hphotos-ak-ash4/270060_1799856805760_1519989351_31482916_3866652_s.jpg",
"link"=>"http://www.facebook.com/photo.php?fbid=1799856805760&set=a.1493877356465.2064294.1519989351&type=1", "name"=>"Mobile Uploads",
"icon"=>"http://static.ak.fbcdn.net/rsrc.php/v1/yx/r/og8V99JVf8G.gif", "type"=>"photo", "object_id"=>"1799856805760", "application"=>{"name"=>"Facebook for Android",
"id"=>"350685531728"}, "created_time"=>"2011-07-03T03:14:04+0000", "updated_time"=>"2011-07-03T03:14:04+0000"}, {"id"=>"2733058_10100271380562998", "from"=>{"name"=>"Joshua Ramirez",
"id"=>"2733058"}, "message"=>"Just posted a photo",
"picture"=>"http://platform.ak.fbcdn.net/www/app_full_proxy.php?app=124024574287414&v=1&size=z&cksum=228788edbab39cb34861aecd197ff458&src=http%3A%2F%2Fimages.instagram.com%2Fmedia%2F2011%2F07%2F02%2F2ad9768378cf405fad404b63bf5e2053_7.jpg",
"link"=>"http://instagr.am/p/G1tp8/", "name"=>"jtrainexpress's photo", "caption"=>"instagr.am",
"icon"=>"http://photos-e.ak.fbcdn.net/photos-ak-snc1/v27562/10/124024574287414/app_2_124024574287414_6936.gif", "actions"=>[{"name"=>"Comment",
"link"=>"http://www.facebook.com/2733058/posts/10100271380562998"}, {"name"=>"Like", "link"=>"http://www.facebook.com/2733058/posts/10100271380562998"}], "type"=>"link",
"application"=>{"name"=>"Instagram", "id"=>"124024574287414"}, "created_time"=>"2011-07-03T02:07:37+0000", "updated_time"=>"2011-07-03T02:07:37+0000"},
{"id"=>"588368718_10150230423643719", "from"=>{"name"=>"Eric Bailey", "id"=>"588368718"}, "link"=>"http://www.facebook.com/pages/Martis-Camp/105474549513998", "name"=>"Martis Camp",
"caption"=>"Eric checked in at Martis Camp.", "description"=>"Rockin the pool", "icon"=>"http://www.facebook.com/images/icons/place.png", "actions"=>[{"name"=>"Comment",
"link"=>"http://www.facebook.com/588368718/posts/10150230423643719"}, {"name"=>"Like", "link"=>"http://www.facebook.com/588368718/posts/10150230423643719"}],
"place"=>{"id"=>"105474549513998", "name"=>"Martis Camp", "location"=>{"city"=>"Truckee", "state"=>"CA", "country"=>"United States", "latitude"=>39.282813917575,
"longitude"=>-120.16736760768}}, "type"=>"checkin", "application"=>{"name"=>"Facebook for iPhone", "id"=>"6628568379"}, "created_time"=>"2011-07-03T01:58:32+0000",
"updated_time"=>"2011-07-03T01:58:32+0000", "likes"=>{"data"=>[{"name"=>"Mike Janes", "id"=>"725535294"}], "count"=>1}}]
I have looked around for clues on this, and haven't found it yet (but I'm still working on my stackoverflow-foo). Any help would be greatly appreciated.
That isn't a Ruby Hash, that's a fragment of a JSON string. First you need to decode into a Ruby data structure:
# If your JSON string is in json...
h = ActiveSupport::JSON.decode(json) # Or your favorite JSON decoder.
Now you'll have a Hash in h so you can access it like any other Hash:
array = h['data']
puts array[0]['id']
# prints out 1111111111_0000000000000
puts array[0]['from']['name']
# prints Jane Done

Resources