Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find and replace within a multidimensional hash - Ruby

Tags:

ruby

hash

If you take a hash:

{
   :element => {
      :to_find => 'found me'
   },
   :element_2 => {
      :inner_element => {
         :n_elements => {
            :to_find => 'found me'
         }
       :do_not_touch => 'still here'
      }
   }
}

How could I find and replace the :to_find with 'changed'?

I have attempted

(hash).update(hash){|k,v| (([:to_find].include? k) ? 'changed' : v}

however this is only one deep.

I could make a recursive function such has as:

def change_keys(hash, keys, new_value)
   (hash).update(hash) do |k,v| 
       if (keys.include? k) 
         new_value
       else
          if v.class == Hash 
            find_key(v)
          else
            v
          end
       end
    end
end

I have tested that running this, works:

change_keys(my_hash, [:to_find], 'changed')

However, is there a cleaner way?

like image 788
ABrowne Avatar asked Jul 03 '26 06:07

ABrowne


1 Answers

A recursive method is the way to go, but you can make it cleaner...

def change_keys(hash, keys, new_value)
    keys.each { |k|  hash[k] = new_value if hash.has_key?(k) }
    hash.values.each { |v| change_keys(v, keys, new_value)  if v.class == Hash }
end
like image 170
SteveTurczyn Avatar answered Jul 05 '26 21:07

SteveTurczyn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!