简体   繁体   中英

Ruby - Iterating over a Nested Hash and counting values

Despite there being many questions on nested hashes I've not found any solutions to my problem.

I'm pulling in strings and matching each character to a hash like so:

numberOfChars = {}
string.each_char do |c|
    RULES.each do |key, value|
        if c === key
            numberOfChars[value] += 1
        end
    end
end

This worked fine and would output something like "a appears 3 times" until I realised that my hash needed to be nested, akin to this:

RULES = {
    :limb {
        :colour {
            'a' => 'foo',
            'b' => 'bar'
        },         
        'c' => 'baz'
    }
}

So how would I go about getting the 'leaf' key and it's value?

While it's iterating over the hash it also needs to count how many times each key appears, eg does 'a' appear more than 'b'? If so add a to new hash. But I'm pretty lost as to how that would work in practice without knowing how it'll be iterating over a nested hash to begin with.

It just seems to me an overly convoluted way of doing this but if anyone's got any pointers they'd be hugely appreciated!

Also, if it's not painfully clear already I'm new to Ruby so I'm probably making some fundamental mistakes.

Are you looking for something like this?

RULES = {
  :limb => {
    :colour => {
      'a' => 'foo',
      'b' => 'bar'
    },
    'c' => 'baz',
    :color => {
      'b' => 'baz'
    }
  }
}

def count_letters(hash, results = {})
  hash.each do |key, value|
    if value.kind_of?(Hash)
      count_letters(value, results)
    else
      results[key] = (results[key] || 0) + 1
    end
  end
  results
end

p count_letters(RULES)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM