user1093111 user1093111 - 2 months ago 7
Ruby Question

Ruby parse csv to usable hash

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?

Answer
  1. 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}
    }
    
  2. 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"