2017-03-07 90 views
0

我是編程新手,正在使用Ruby來熟悉語法和控制流。查找散列數組中的所有最大值,然後存儲在單獨的數組中Ruby

我正在製作的節目要求我放置具有最長播放時間的DVD名稱。這裏是我的代碼:

dvds = [ 
    { 
    :dvd_name=>"x-men", 
    :dvd_playing_time=>549, 
    :times_played=>9.0 
    }, 
    { 
    :dvd_name=>"Pi", 
    :dvd_playing_time=>549, 
    :times_played=>6.0 
    } 
] 

兩個哈希有549dvd_playing_time,所以我想在存儲陣列都"x-men""Pi"。我試過max_by,但它只返回一個dvd_name

dvds.max_by { |length| length[:dvd_playing_time]}[:dvd_name] 

任何幫助你可以提供的是太棒了!

+1

因爲有些讀者,尤其是那些英文是第二語言的讀者,可能認爲你指的是':times_played',所以製作關鍵字':dvd_length':dvd_playing_time'會更清楚。另外,使兩個哈希的':times_played'的值不同會更好。 –

+0

Cary Swoveland,謝謝你的建議。我會修改我的符號,使之更清晰。 – aprogrammer

+0

我編輯:dvd_length到:dvd_playing_time並且也改變了:times_played值不同。 – aprogrammer

回答

3

有三個步驟來獲得答案。

  • 確定最長播放時間,由荷蘭國際集團Enumerable#map每個哈希hh[:dvd_length],然後取這些值的Enumerable#max
  • 使用Hash#select選擇散列h,其中h[:dvd_length]等於最大播放時間。
  • Enumerable#map這些哈希值h最大播放時間爲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 
+0

非常感謝!你的代碼很好地工作。 – aprogrammer

1

如果你想要做一個行:

dvds.group_by{ |dvd| dvd[:dvd_playing_time] }.max.last.map{ |dvd| dvd[:dvd_name] } 

該代碼組由長度的DVD光盤,需要與最大長度的組,並將其映射到只包含dvd名稱。這不是最快的選擇,因爲它會在陣列中運行幾次(技術上n + g + m次)。

如果您擔心速度:

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 

這種算法,同時不雅,會給你通過數組,這是你能做的最好的一個迭代的答案。

+0

非常好的答案。 1)值得注意的是(討論#2時)#1需要2到3次通過陣列。 2)#1中的'max'很好,'max_by(&:first)'可能更清晰。 3)在#2中,你可以編寫'dvds.each_with_object([])do | dvd,longest | ...'這樣你就不必在最後加上'longest',例如,如果你用方法包裝它。 –

+0

@CarySwoveland你知道,如果each_with_object在我發現一個新的max並且舊的數組必須被丟棄的時候傳遞給'longest'的新引用會好嗎?我擔心它會迫使我使用相同的數組,這會更慢。 – eiko

+0

這不是速度問題。當'longest'是一個塊變量時,它不會與'longest = [dvd [:dvd_name]]'一起工作。 (分配會改變最長的'object_id'。)在這種情況下,您需要'longest.replace([dvd [:dvd_name]])''。 ('longest << dvd [:dvd_name]'是好的。)另外,你有一個錯字:'dvd [:dvd_length == max]'中的右括號錯誤放置。 –

相關問題