David Johnson
David Johnson

Reputation: 46

Counting the number of times a value is repeated in a Hash

I am pulling a hash from mashable.com, and I need to count instances of author names (author is the key, and the value is the author name). mashable's api

{
new: [
{   
    other_keys: 'other_values'...
    author: 'Author's Name'
}
]

I want to iterate over the hash and pull out the author's name, and then count the amount of times it is repeated in the entire list from the mashable api.

Here is what I have; it turns the hash into an array, iterates over it, adding the count to each author name as the key, and then adds the number of repeats as the value.

This would be great, but I can't get it back into my original hash from mashable to add all of the other hash items I want to display.

all_authors = []

all_stories.each do |story|
    authors = story['author']
    all_authors << authors
end

counts = Hash.new(0)

all_authors.each do |name|
    counts[name] += 1
end

counts.each do |key, val|
    puts "#{key}: " "#{val}"
end

That does what it is supposed to, but I try to put it back into the original hash from mashable:

   all_stories.each do |com|
    plorf = com['comments_count'].to_i
    if plorf < 1
        all_stories.each do |story|
            puts "Title:\n"
            puts story['title']
            puts "URL:\n"
            puts story['short_url']
            puts "Total Shares:\n"
            puts story['shares']['total']
        end
    end
   end

When I drop the code back in to that iteration, all it does is iterate of the initial has, and after each entry, I get a list of all authors and the number of stories they have written, instead of listing each author connected to the other information about each story and the number of stories they have written.

Any help is greatly appreciated.

Upvotes: 1

Views: 2345

Answers (2)

David Johnson
David Johnson

Reputation: 46

@Michael Kohl it was a good answer, I think I was asking the question wrong. I wound up doing this:

author = story['author']
puts "Number of stories by #{story['author']}: #{author_count['author']}"

inside my "all_stories" loop...

yeah I am pretty sure I was trying to "re-inject" the values to the original hash, and that was way wrong...

Thanks so much for your help though

Upvotes: 0

Michael Kohl
Michael Kohl

Reputation: 66837

Here's a simplified version:

h = { a: 1, b: 2, c: 1, d: 1 }
h.count { |_, v| v == 1 } #=> 3
h.values.count(1)         #=> 3

Alternatively you can also group by key and then count:

 h.group_by(&:last).map { |v, a| [v, a.count] }.to_h #=> {1=>3, 2=>1}

This groups the hash by its values, the counts the times elements in the array of key/value pairs. Here's a more explicit version:

  grouped = h.group_by(&:last) #=> {1=>[[:a, 1], [:c, 1], [:d, 1]], 2=>[[:b, 2]]}
  grouped.map { |v, a| [v, a.count] #=> [[1, 3], [2, 1]]

Then the final to_h turns the array of 2 element arrays into a hash.

Upvotes: 2

Related Questions