I have the following hashes:
WorkersPay
:
{"Aaron"=>[300], "Alex"=>[684], ... , "Wendy"=>[792] , "Zach"=>[281]}
and WorkersHrs
:
{"Aaron"=>[36], "Alex"=>[34], ... , "Wendy"=>[39], "Zach"=>[42]}
Where the ellipses (...) indicate a countably infinite number of names between, "Alex," and, "Wendy."
I want to accomplish two things:
puts "#{worker} worked #{hours} and earned
$#{dollars}.00"
for every worker in both WorkersPay and WorkersHrsputs "#{worker} worked #{hours} this week"
)I have searched through SO for days and this is my best code so far:
WorkerHrs.each do |key, array|
WorkerHrs.sort_by { |a, b| a[0] <=> b[0] }
WorkerPay.each do |key2, array2|
if key == key2
if array.inject{|a,i| a*10 + i} == 0
puts "#{key} worked #{array.inject{|a,i| a*10 + i}} hours this week"
else
puts "#{key} worked #{array.inject{|a,i| a*10 + i}} hours and earned $#{array2.inject{|a,i| a*10 + i}}.00"
end
end
end
end
Hoping to achieve this:
John worked 80 hours and earned $36.00
.
.
.
Sam worked 0 hours this week
Where the vertical ellipses indicate the exact same thing as the regular ellipses.
I have never worked with hashes that contain key, array pairs before and would appreciate any and all help getting my horrendous code to work!
Note that in Ruby, if you sort a Hash, then Ruby will first convert it to an array of arrays where the "inner" arrays are of 2 elements each: the key and the value.
To sort the WorkHrs
, then, you only need this:
SortHrs = WorkHrs.sort_by { |wh| wh[1] }.reverse # reverse order of hours
This says you want to sort your array of arrays by the second element of each internal array. This is short-hand for, WorkHrs.sort_by { |a,b| a[1] <=> b[1] }
since a <=> b
is the default comparison method.
Implicitely, Ruby will make WorkHrs
look like this before sorting:
[["Aaron", [36]], ["Alex", [34]], ... , ["Wendy", [39]], ["Zach", [42]]]
wh[1]
is the value of the key-value pair of the array element (wh[0]
would be the key).
Then you process it:
SortHrs.each do |wh|
if wh[1] == 0 # Hours worked is 0?
puts "#{wh[0]} worked 0 hours this week"
else
puts "#{wh[0]} worked #{wh[1]} hours and earned $#{WorkersPay[wh[0]].first}"
end
end
Here, WorkersPay[wh[0]]
uses wh[0]
(the person's name) as a key to access the hash for pay. The .first
gets the first (and, in this case, the only) element. You could also use, WorkersPay[wh[0]][0]
.
That's about all there is to it. I will leave the formatting of the pay amount as an exercise. Look up Ruby string formatting for information.