2011-08-02 77 views
0

我有獲取嵌套元素的頻率,與關係保留

  • 商店對象數組

    • 屬於城市對象

      • 屬於縣對象

我想通過縣,然後城市,那麼頻率上市的哈希落得...

我想出了這一點,但感覺真的未rubylike ..

city_by_prefecture = shop_list.reduce({}){ |h,e| 
    if h[e.prefecture.name].nil? 
    h[e.prefecture.name] = {e.city.name => 1} 
    elsif h[e.prefecture.name][e.city.name].nil? 
    h[e.prefecture.name][e.city.name] = 1 
    else 
    h[e.prefecture.name][e.city.name] += 1 
    end 
    h 
} 

必須有DRY-er的方式來做到這一點!

+0

可能重複的[如何分配散列\ [ 「一」 \] \ [ 「b」 的\] = 「C」,如果散列\ [ 「一」 \]不存在?] (http://stackoverflow.com/questions/5878529/how-to-assign-hashab-c-if-hasha-doesnt-exist) –

+1

你可能想使用'h.has_key?(e.prefecture.name)'而不是'h [e.prefecture.name] .nil?',因爲這樣你的問題就更加明顯了。另外,使用'each_with_object'而不是'reduce',所以你不必在塊的末尾加上'h'。 –

+0

謝謝安德魯。我不知道'each_with_object'。 – minikomi

回答

1
city_by_prefecture = shop_list.each_with_object({}){ |e,h| 
    h[e.prefecture.name] ||= Hash.new(0) 
    h[e.prefecture.name][e.city.name] += 1 
} 
+0

更清潔!謝謝。 – minikomi

0
shops = [ 
    OpenStruct.new(:prefacture => "pre1", :city => "city1"), 
    OpenStruct.new(:prefacture => "pre1", :city => "city1"), 
    OpenStruct.new(:prefacture => "pre1", :city => "city2"), 
    OpenStruct.new(:prefacture => "pre2", :city => "city3"), 
] 

counts = Hash[shops.group_by(&:prefacture).map do |prefacture, shops_in_prefacture| 
    [prefacture, Hash[shops_in_prefacture.group_by(&:city).map do |city, shops_in_city| 
    [city, shops_in_city.size] 
    end]] 
end] 
# {"pre1"=>{"city1"=>2, "city2"=>1}, "pre2"=>{"city3"=>1}}