Reputation: 45
I am new to programming and am using Ruby to get familiar with syntax and control flow.
The program I am working on wants me to puts the dvd name that has the longest playing time. Here is my code:
dvds = [
{
:dvd_name=>"x-men",
:dvd_playing_time=>549,
:times_played=>9.0
},
{
:dvd_name=>"Pi",
:dvd_playing_time=>549,
:times_played=>6.0
}
]
Both hashes have dvd_playing_time
of 549
, so I want both "x-men"
and "Pi"
stored in an array. I tried max_by
, but it only returns one dvd_name
.
dvds.max_by { |length| length[:dvd_playing_time]}[:dvd_name]
Any help you can provide is fantastic!
Upvotes: 0
Views: 136
Reputation: 5345
If you want to do it in one line:
dvds.group_by{ |dvd| dvd[:dvd_playing_time] }.max.last.map{ |dvd| dvd[:dvd_name] }
This code groups the dvds by length, takes the group with the max length, and maps it to only contain the dvd names. It's not the fastest option since it'll run through the array a few times (n + g + m times, technically).
If you're concerned about speed:
max = 0
longest = []
dvds.each do |dvd|
if dvd[:dvd_playing_time] > max
max = dvd[:dvd_playing_time]
longest = [dvd[:dvd_name]]
elsif dvd[:dvd_playing_time] == max
longest << dvd[:dvd_name]
end
end
This algorithm, while inelegant, will give you the answer with a single iteration through the array, which is the best you can do.
Upvotes: 1
Reputation: 110675
There are three steps to get an answer.
h
to h[:dvd_length]
and then taking the Enumerable#max of those values. h
for which h[:dvd_length]
equals that maximum playing time. Enumerable#map
those hashes h
with the maximum playing time to h[:dvd_name]
.length_of_longest = dvds.map { |h| h[:dvd_length] }.max
#=> 549
puts dvds.select { |h| h[:dvd_length] == length_of_longest }.map { |h| h[:dvd_name] }
# x-men
# Pi
Upvotes: 3