计算哈希值中唯一出现的值

时间:2014-11-14 22:50:23

标签: ruby hash

我正在尝试计算与散列中的正则表达式匹配的唯一值的出现次数。

如果有三个不同的值,多​​次,我想知道每个值发生了多少。

这是我为实现这一目标而开发的代码:

def trim(results)
  open = []

  results.map { |k, v| v }.each { |n| open << n.to_s.scan(/^closed/) }
  puts open.size
end

由于某种原因,它返回所有值的长度,而不仅仅是我尝试匹配的值。我也试过使用results.each_value,但没有用。

4 个答案:

答案 0 :(得分:1)

这样的东西?

hash = {a: 'foo', b: 'bar', c: 'baz', d: 'foo'}
groups = hash.group_by{ |k, v| v[/(?:foo|bar)/] } 
# => {"foo"=>[[:a, "foo"], [:d, "foo"]],
#     "bar"=>[[:b, "bar"]],
#     nil=>[[:c, "baz"]]}

请注意,有一个nil键,这意味着正则表达式与任何内容都不匹配。我们可以摆脱它,因为我们(可能)不关心。或许你可以关心,在这种情况下,不要摆脱它。

groups.delete(nil)

这会计算匹配“匹配”的数量:

groups.map{ |k, v| [k, v.size] }
# => [["foo", 2], ["bar", 1]]

group_by是一种神奇的方法,值得学习。

答案 1 :(得分:1)

 def count(hash, pattern)
   hash.each_with_object({}) do |(k, v), counts| 
     counts[k] = v.count{|s| s.to_s =~ pattern}
   end
 end

 h = { a: ['open', 'closed'], b: ['closed'] }
 count(h, /^closed/)
 => {:a=>1, :b=>1}

这对你有用吗?

答案 2 :(得分:1)

另一种方式:

hash = {a: 'foo', b: 'bar', c: 'baz', d: 'foo'}

hash.each_with_object(Hash.new(0)) {|(k,v),h| h[v]+=1 if v.start_with?('foo')} 
  #=> {"foo"=>2}

hash.each_with_object(Hash.new(0)) {|(k,v),h| h[v]+=1 if v =~ /^foo|bar/} 
  #=> {"foo"=>2, "bar"=>1}

答案 3 :(得分:0)

我认为值得为RUBY_VERSION #=> "2.7.0"更新,其中引入了Enumerable#tally

h = {a: 'foo', b: 'bar', c: 'baz', d: 'foo'}
h.values.tally #=> {"foo"=>2, "bar"=>1, "baz"=>1}
h.values.tally.select{ |k, _| k=~ /^foo|bar/ } #=> {"foo"=>2, "bar"=>1}