2015-05-18 127 views
1

我有一個Ruby的哈希值:集團由數組元素的散列內,計算計數

example = { 
    :key1 => [1, 1, 4], 
    :key2 => [1, 2, 3], 
    :key3 => [1, 3, 2], 
    :key4 => [1, 5, 0], 
    :key5 => [1, 7, 2], 
    :key6 => [2, 1, 5], 
    :key7 => [2, 2, 4], 
    :key8 => [2, 4, 2], 
    :key9 => [3, 1, 6], 
    :key10 => [3, 2, 5], 
    :key11 => [3, 3, 4] 
} 

我怎麼能羣的混雜由值的數組中的第一個元素?一旦分組後,我如何計算每個組的數量並將它們存儲到其他散列中?

我打算跳過group_by部分,如果我能夠提取計數。

實施例所需的輸出:

groups = {:group1 => 5, :group2 => 3, :group3 => 3} 

回答

5

下面是使用each_with_object方式:

example.each_with_object(Hash.new(0)) { |(_, (v, *)), h| h[:"group#{v}"] += 1 } 
# => {:group1=>5, :group2=>3, :group3=>3} 
0

這是爲了做到這一點的一種方法:

example.values.group_by(&:first).each_with_object({}) { |(k,v),h| 
    h.update("group#{k}".to_sym=>v.size) } 
    #=> {:group1=>5, :group2=>3, :group3=>3} 

的步驟:

example = {:key1=> [1, 1, 4], :key2=> [1, 2, 3], :key3=>[1, 3, 2], 
      :key4=> [1, 5, 0], :key5=> [1, 7, 2], :key6=>[2, 1, 5], 
      :key7=> [2, 2, 4], :key8=> [2, 4, 2], :key9=>[3, 1, 6], 
      :key10=>[3, 2, 5], :key11=>[3, 3, 4]} 
v = example.values 
    #=> [[1, 1, 4], [1, 2, 3], [1, 3, 2], [1, 5, 0], [1, 7, 2], [2, 1, 5], 
    # [2, 2, 4], [2, 4, 2], [3, 1, 6], [3, 2, 5], [3, 3, 4]] 
g = v.group_by(&:first) # same as group_by { |k,_| k } 
    #=> {1=>[[1, 1, 4], [1, 2, 3], [1, 3, 2], [1, 5, 0], [1, 7, 2]], 
    # 2=>[[2, 1, 5], [2, 2, 4], [2, 4, 2]], 
    # 3=>[[3, 1, 6], [3, 2, 5], [3, 3, 4]]} 
enum = g.each_with_object({}) 
    #=> #<Enumerator: { 1=>[[1, 1, 4], [1, 2, 3], [1, 3, 2], [1, 5, 0], [1, 7, 2]], 
    #     2=>[[2, 1, 5], [2, 2, 4], [2, 4, 2]], 
    #     3=>[[3, 1, 6], [3, 2, 5], [3, 3, 4]] 
    #     }:each_with_object({})> 

轉換枚舉到陣列以檢查其值:

enum.to_a 
    #=> [[[1, [[1, 1, 4], [1, 2, 3], [1, 3, 2], [1, 5, 0], [1, 7, 2]]], {}], 
    # [[2, [[2, 1, 5], [2, 2, 4], [2, 4, 2]]], {}], 
    # [[3, [[3, 1, 6], [3, 2, 5], [3, 3, 4]]], {}]] 

請注意哈希的值,它目前是空的。合格enum的第一個元素塊:

(k,v),h = enum.next 
    #=> [[1, [[1, 1, 4], [1, 2, 3], [1, 3, 2], [1, 5, 0], [1, 7, 2]]], {}] 
k #=> 1 
v #=> [[1, 1, 4], [1, 2, 3], [1, 3, 2], [1, 5, 0], [1, 7, 2]] 
h #=> {} 
h.update("group#{k}".to_sym=>v.size) 
    #=> {}.update(:group1=>5) 
    #=> {:group1=>5} (new value of h) 

如果我們現在研究的enum的元素,我們看到的散列值進行了更新:

enum.to_a 
    #=> [[[1, [[1, 1, 4], [1, 2, 3], [1, 3, 2], [1, 5, 0], [1, 7, 2]]], 
    #  {:group1=>5}], 
    # [[2, [[2, 1, 5], [2, 2, 4], [2, 4, 2]]], {:group1=>5}], 
    # [[3, [[3, 1, 6], [3, 2, 5], [3, 3, 4]]], {:group1=>5}]] 

繼續...

(k,v),h = enum.next 
    #=> [[2, [[2, 1, 5], [2, 2, 4], [2, 4, 2]]], {:group1=>5}] 
k #=> 2 
v #=> [[2, 1, 5], [2, 2, 4], [2, 4, 2]] 
h #=> {:group1=>5} 
h.update("group#{k}".to_sym=>v.size) 
    #=> {:group1=>5, :group2=>3} 

(k,v),h = enum.next 
    #=> [[3, [[3, 1, 6], [3, 2, 5], [3, 3, 4]]], {:group1=>5, :group2=>3}] 
h.update("group#{k}".to_sym=>v.size) 
    #=> {:group1=>5, :group2=>3, :group3=>3} 
0

或者它可能是這樣的更清楚:

arrays_by_first_element = example.values.group_by { |a| a[0] } 
groups = {} 
arrays_by_first_element.each { |k, v| groups[k] = v.size } 
0

簡單的一個班輪:

puts example.map{|k,v| v[0]}.inject(Hash.new(0)) { |total, e| total[("group%s" % e)] += 1; total} 

輸出:

{"group1"=>5, "group2"=>3, "group3"=>3} 
1

這裏是一個 「易」 的版本(於數組w/o鍵):

example.group_by { |k, v| v.first }.values.map(&:count)