tomet
tomet

Reputation: 2566

Add something to hash value if key exists?

I have a Hash in Ruby:

hash = Hash.new

It has some key value pairs in it, say:

hash[1] = "One"
hash[2] = "Two"

If the hash contains a key 2, then I want to add "Bananas" to its value. If the hash doesn't have a key 2, I want to create a new key value pair 2=>"Bananas".

I know I can do this by first checkng whether the hash has the key 2 by using has_key? and then act accordingly. But this requires an if statement and more than one line.

So is there a simple, elegant one-liner for achieving this?

Upvotes: 10

Views: 12495

Answers (5)

ipopa
ipopa

Reputation: 1223

You can initialise the hash with a block and then directly concatenate:

hash = Hash.new {|hash, key| hash[key] = ""}
hash[1] << "One"
hash[2] << "Two"
hash[2] << "Bananas"

{1=>"One", 2=>"TwoBananas"}

Upvotes: 0

mralexlau
mralexlau

Reputation: 2003

You could set the default value of the hash to an empty string, then make use of the << operator to concat whatever new values are passed:

h = Hash.new("")
#=> {}
h[2] << "Bananas"
#=> "Bananas" 
h
#=> {2=>"Bananas"} 
h[2] << "Bananas"
#=> "BananasBananas" 

Per @rodrigo.garcia's comment, another side effect of this approach is that Hash.new() sets the default return value for the hash (which may or may not be what you want). In the example above, that default value is an empty string, but it doesn't have to be:

h2 = Hash.new(2)
#=> {}
h2[5] 
#=> 2

Upvotes: 5

Kyle Roberts
Kyle Roberts

Reputation: 11

Technically, both your roads lead to the same place. So Hash[2] = "bananas" produces the same result as first checking the hash for key 2. However, if you actually need the process of checking the hash for some reason a way to do that is use the .has_key? method, and a basic if conditional.

Suppose there is a hash,

`Hash = { 1 => "One", 2 => "Two" }`

setup a block of code based on the truth-value of a key search,

if hash.has_key?(2) == true hash[2] = "bananas" else hash[2] = "bananas" end

or more simply,

hash.has_key?(2) == true ? hash[2] = "bananas" : hash[2] = "bananas"

Upvotes: 1

David Grayson
David Grayson

Reputation: 87531

This works:

hash[2] = (hash[2] || '') + 'Bananas'

If you want all keys to behave this way, you could use the "default" feature of Ruby's Hash:

hash = {}
hash.default_proc = proc { '' }
hash[2] += 'Bananas'

Upvotes: 11

sawa
sawa

Reputation: 168269

(hash[2] ||= "").concat("Bananas")

Upvotes: 4

Related Questions