Reputation:
With Ruby 2.4, I want to count the number of occurrences of an element and store them in a hash. However, I don't want to include any nil keys in my hash. So I tried
my_hash = int_data_col.each_with_object(Hash.new(0)) { |i, h| h[i]+=1 }.delete(nil)
but this returns "1". If I leave off the "delete(nil)", it returns a hash, but then a nil key is included in the hash (assuming a nil was present in the "int_data_col" array). How do I remove the nil key from my hash and still get the correct results?
Upvotes: 3
Views: 2170
Reputation: 37517
In Ruby 2.4, there's a way to do it which is very readable:
arr.compact.group_by(&:itself).transform_values(&:size)
Upvotes: 2
Reputation: 195
If you want to clean up the array prior to hashing it, then
int_data_col.compact!
int_data_col.each_with_object(Hash.new(0)) {|i, h| h[i]+=1 }
If you want to simply create the hash, ignoring nil, without disturbing the original array, then the following as suggested by @sagarpandya82
int_data_col.compact.each_with_object(Hash.new(0)) { |i, h| h[i]+=1 }
When you had specified .delete(nil)
, I think you were expecting it to return the hash with the nil key removed. But what it did was remove the nil key and returned the count value of the nil key (1). From the Hash Class doc, "Deletes the key-value pair and returns the value from hash whose key is equal to key."
Upvotes: 0
Reputation: 9508
Use Array#compact
which removes all nil
values before the count.
my_hash = int_data_col.compact.each_with_object(Hash.new(0)) { |i, h| h[i]+=1 }
Upvotes: 2