2017-07-03 94 views
2

我有一個哈希數組,其中鍵爲國家,值爲天數。Ruby集合哈希集合中的選擇性值

我想彙總哈希值並且總結相同國家的值。

的陣列可以是這樣的countries = [{"Country"=>"Brazil", "Duration"=>731/1 days}, {"Country"=>"Brazil", "Duration"=>365/1 days}]

我想這個對的行返回的東西:對SO like this one

countries.inject{|new_h, old_h| new_h.merge(old_h) {|_, old_v, new_v| old_v + new_v}} 

[{"Country" => "Brazil", "Duration"=>1096/1 days}]

我試過其他問題可生產{"Country"=>"BrazilBrazil", "Duration"=>1096/1 days}

有沒有辦法選擇性地只合並特定的值UE的?

回答

2

如下您可以更新您的代碼:

countries.inject do |new_h, old_h| 
    new_h.merge(old_h) do |k, old_v, new_v| 
     if k=="Country" then old_v else old_v + new_v end 
    end 
end 
# => {"Country"=>"Brazil", "Duration"=>1096} 

,你基本上使用k(用於關鍵)的說法不同的合併策略之間切換。

+0

傳說!謝謝@metaphori – TheLegend

4

這使用Hash::new的形式創建一個帶默認值的空散列(此處爲0)。對於以這種方式創建的散列h,如果散列沒有密鑰k,則h[k]返回默認值。散列不被修改。

countries = [{"Country"=>"Brazil", "Duration"=>"731/1 days"}, 
      {"Country"=>"Argentina", "Duration"=>"123/1 days"}, 
      {"Country"=>"Brazil", "Duration"=>"240/1 days"}, 
      {"Country"=>"Argentina", "Duration"=>"260/1 days"}] 

countries.each_with_object(Hash.new(0)) {|g,h| h[g["Country"]] += g["Duration"].to_i }. 
    map { |k,v| { "Country"=>k, "Duration"=>"#{v}/1 days" } } 
    #=> [{"Country"=>"Brazil", "Duration"=>"971/1 days"}, 
    # {"Country"=>"Argentina", "Duration"=>"383/1 days"}] 

第一個散列傳遞給塊並分配給塊變量g

g = {"Country"=>"Brazil", "Duration"=>"731/1 days"} 

在這個時候h #=> {}。然後我們計算

h[g["Country"]] += g["Duration"].to_i 
    #=> h["Brazil"] += "971/1 days".to_i 
    #=> h["Brazil"] = h["Brazil"] + 971 
    #=> h["Brazil"] = 0 + 971 # h["Brazil"] 

爲什麼"971/1 days".to_i回報971的說明,請參見String#to_i

上的平等權h["Brazil"]返回0因爲h沒有(還)有一個關鍵"Brazil"的默認值。請注意,右側的h["Brazil"]h.[]("Brazil")的語法糖,而左側則是語法糖h.[]=(h["Brazil"] + 97)。它是Hash#[],當散列沒有給定的鍵時,它返回默認值。其餘的步驟是相似的。

+0

'Hash.new(0)'會將持續時間轉換爲秒。你可能想嘗試做'Hash.new(0.days)',然後在地圖塊內部,你可以做''Duration'=> v' – TheLegend

+1

@TheLegend,謝謝你的建議。我不知道Rails,所以我給了一個純Ruby解決方案。 –