Ruby Hash is a destructive and non-destructive method

Couldn't find a previous post that answers my question ... I'm looking into using destructive and non-destructive methods in Ruby. I found an answer to an exercise I'm working on (destructive addition of a number to hash values), but I want to be clear about why some of my earlier solutions didn't work. Here's an answer that works:

  def modify_a_hash(the_hash, number_to_add_to_each_value)
    the_hash.each { |k, v| the_hash[k] = v + number_to_add_to_each_value}
  end

      

These two solutions come back as non-destructive (since they all use "each", I can't figure out why. To do something destructive, is the equal sign above that does the trick?):

  def modify_a_hash(the_hash, number_to_add_to_each_value)
    the_hash.each_value { |v| v + number_to_add_to_each_value}
  end

  def modify_a_hash(the_hash, number_to_add_to_each_value)
    the_hash.each { |k, v| v + number_to_add_to_each_value}
  end

      

+3


source to share


2 answers


The terms "destructive" and "non-destructive" are a little misleading here. Better to use standard terminology "in place" and "returns a copy".

Usually, methods that change place are appended !

to the name to serve as a warning, for example gsub!

String. Some methods prior to this convention do not have them, for example push

Array.

=

performs the task in a loop. Your other examples are not really helpful as it each

returns the original object that is iterated over regardless of the results.

If you want to return a copy, you must do this:



def modify_a_hash(the_hash, number_to_add)
  Hash[
    the_hash.collect do |k, v|
      [ k, v + number_to_add ]
    end
  ]
end

      

This will return a copy. The inner operation collect

converts the key-value pairs to new key-value pairs with the setting applied. No =

, as there is no destination.

The external method will Hash[]

convert these key-value pairs to the correct Hash object. Then it comes back and is independent of the original.

Typically, a non-destructive or "copy-back" method is to create a new independent version of what it is manipulating in order to store the results. This applies to String, Array, Hash, or any other class or container you can work with.

+2


source


Perhaps this slightly different example will be helpful.

We have a hash:

2.0.0-p481 :014 > hash
 => {1=>"ann", 2=>"mary", 3=>"silvia"}

      

Then we iterate over it and change all letters to uppercase:



2.0.0-p481 :015 > hash.each { |key, value| value.upcase! }
 => {1=>"ANN", 2=>"MARY", 3=>"SILVIA"}

      

The original hash changed because we were using upcase! Method.

Compare with the method without! a sign that doesn't change the hash value:

2.0.0-p481 :017 > hash.each { |key, value| value.downcase }
=> {1=>"ANN", 2=>"MARY", 3=>"SILVIA"}

      

0


source







All Articles