2

I am trying to update my hash's values after subtracting the values by three. For example,

extinct_animals = {
  "Passenger Pigeon" => 1914,
  "Tasmanian Tiger" => 1936,
  "Eastern Hare Wallaby" => 1890,
  "Dodo" => 1662,
  "Pyrenean Ibex" => 2000,
  "West African Black Rhinoceros" => 2011,
  "Laysan Crake" => 1923
}

I have this code, which sets the values to subtract three:

extinct_animals.each {|animal, year| puts year - 3}

and the output:

1911
1933
1887
1659
1920

How do I return the entire hash with the keys and new values?

4
  • 1
    Possible duplicate of How to change Hash values? Commented Dec 19, 2018 at 2:39
  • @anothermh, a dup? Yes, I think so, but it nicely illustrates the pitfalls of closing a question for that reason. In this case the method transform_values! would not make it into the Ruby core until eight years after the original question was asked. Also, we've all seen answers offered to questions that were far superior to the answers given to the earlier question. Of course, the great answer could always be added to those given to the duped question, but it won't have much visibility, particularly when, as here, the duped question is ancient. I don't have an answer, but it is a problem. Commented Dec 19, 2018 at 3:50
  • @CarySwoveland I would prefer seeing this question closed as a duplicate so users are directed to the one linked above, where you will find transform_values as the second highest voted answer with a score of 61. It would seem that the issue of "visibility" for that answer is non-existent; I don't agree that there is any problem with closing this. Commented Dec 19, 2018 at 4:00
  • I hadn't noticed that answer, which was submitted eight years after the question wss posted, but yes, you have a point. Commented Dec 19, 2018 at 6:13

2 Answers 2

5

You'll want to use Hash#transform_values!, which made its debut in MRI v2.4:

extinct_animals.transform_values! { |v| v - 3 }
  #=> {"Passenger Pigeon"=>1911, "Tasmanian Tiger"=>1933,
  #    "Eastern Hare Wallaby"=>1887, "Dodo"=>1659, "Pyrenean Ibex"=>1997,
  #    "West African Black Rhinoceros"=>2008, "Laysan Crake"=>1920}

extinct_animals
  #=> {"Passenger Pigeon"=>1911, "Tasmanian Tiger"=>1933,
  #    "Eastern Hare Wallaby"=>1887, "Dodo"=>1659, "Pyrenean Ibex"=>1997,
  #    "West African Black Rhinoceros"=>2008, "Laysan Crake"=>1920}
Sign up to request clarification or add additional context in comments.

Comments

0

Within the block, make sure you are modifying the hash by using =:

extinct_animals.each { |animal, year| extinct_animals[animal] = year - 3 }
=> {
  "Passenger Pigeon" => 1911,
  "Tasmanian Tiger" => 1933,
  "Eastern Hare Wallaby" => 1887,
  "Dodo" => 1659,
  "Pyrenean Ibex" => 1997,
  "West African Black Rhinoceros" => 2008,
  "Laysan Crake" => 1920
}

Don't use puts. That just writes out to the console.

A more brief version of this solution would be:

extinct_animals.each { |animal, _year| extinct_animals[animal] -= 3 }

Here we prefix year with an underscore to indicate that the variable is not used within the block.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.