我正在尝试计算与散列中的正则表达式匹配的唯一值的出现次数。
如果有三个不同的值,多次,我想知道每个值发生了多少。
这是我为实现这一目标而开发的代码:
def trim(results)
open = []
results.map { |k, v| v }.each { |n| open << n.to_s.scan(/^closed/) }
puts open.size
end
由于某种原因,它返回所有值的长度,而不仅仅是我尝试匹配的值。我也试过使用results.each_value
,但没有用。
答案 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}