8

I have a hash in which I want to use the values as keys in a new Hash which contains a count of how many times that item appeared as a value in the original hash.

So I use:

hashA.keys.each do |i|
    puts hashA[i]
end

Example output:

0
1
1
2
0
1
1

And I want the new Hash to be the following:

{ 0 => 2,  1 => 4,  2 => 1 }
Derek
  • 9,773
  • 7
  • 29
  • 34
  • possible duplicate of [How to count identical string elements in a Ruby array](http://stackoverflow.com/questions/5128200/how-to-count-identical-string-elements-in-a-ruby-array). The original data structure in this question is a hash, but you're throwing away the keys, so you're effectively dealing with `hashA.values`, which is an array. – Andrew Grimm Oct 24 '11 at 01:15
  • @AndrewGrimm Meh; eventually (and quickly), yes... But when searching with a "I have a map" mindset you probably won't search for stuff about arrays. – Dave Newton Oct 24 '11 at 01:17

2 Answers2

17
counts = hashA.values.inject(Hash.new(0)) do |collection, value|
  collection[value] +=1
  collection
end
Brian Rose
  • 1,725
  • 13
  • 10
7

TL;DR: hashA.values.inject(Hash.new(0)) { |m, n| m[n] += 1; m }

> hashA = { a: 0, b: 1, c: 1, d: 2, e: 0, f: 1, g: 1 }
=> {:a=>0, :b=>1, :c=>1, :d=>2, :e=>0, :f=>1, :g=>1} 
> hashCounts = hashA.values.inject(Hash.new(0)) { |m, n| m[n] += 1; m }
=> {0=>2, 1=>4, 2=>1} 
Dave Newton
  • 158,873
  • 26
  • 254
  • 302