Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I increment a value for an uninitialized key in a hash?

Tags:

hashtable

ruby

If I try to increment the value for a key that does not yet exist in a hash like so

h = Hash.new
h[:ferrets] += 1

I get the following error:

NoMethodError: undefined method `+' for nil:NilClass

This makes sense to me, and I know this must be an incredibly easy question, but I'm having trouble finding it on SO. How do I add and increment such keys if I don't even know in advance what keys I will have?

like image 852
labyrinth Avatar asked May 29 '14 03:05

labyrinth


People also ask

How to increment the value of a map key?

To increment the value of a key, you can do as follow, get the value, and put it again with +1, because the key already exists it will just replace the existing one (keys in a map are unique) : 3. To have a more generic solution you could do :

How to let auto_increment sequence start with another value?

By default, the starting value for AUTO_INCREMENT is 1, and it will increment by 1 for each new record. To let the AUTO_INCREMENT sequence start with another value, use the following SQL statement:

How do you increment a key in unordered_map?

Once the key is found, we can increment its value using the ++ operator on the second member function of the pair pointed by the iterator. If the key is not found, we can insert it into the map with value 1 using unordered_map::insert with std::make_pair.

How to increment a variable in Bash?

You can create a Bash file in your Home directory with any name of your preference, then followed by a “.sh” extension. In this script, we have declared a variable “x” and initialized it with the value “0”. Then we have another variable, “a”, where we assigned the post incremented value of the variable “x”.


2 Answers

you can set default value of hash in constructor

h = Hash.new(0)
h[:ferrets] += 1
p h[:ferrets]

note that setting default value has some pitfalls, so you must use it with care.

h = Hash.new([]) # does not work as expected (after `x[:a].push(3)`, `x[:b]` would be `[3]`)
h = Hash.new{[]} # also does not work as expected (after `x[:a].push(3)`  `x[:a]` would be `[]` not `[3]`)
h = Hash.new{Array.new} # use this one instead

Therefore using ||= might be simple in some situations

h = Hash.new
h[:ferrets] ||= 0
h[:ferrets] += 1
like image 59
ymonad Avatar answered Oct 31 '22 16:10

ymonad


One way to fix this is to give your hash a default:

h = Hash.new
h.default = 0
h[:ferrets] += 1

puts h.inspect
#{:ferrets=>1}

The default default for a hash is nil, and nil doesn't understand how to ++ itself.

h = Hash.new{0} 
h = Hash.new(0) # also works (thanks @Phrogz)

Is another way to set the default while declaring it.

like image 41
John C Avatar answered Oct 31 '22 17:10

John C