2015-05-18 86 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)