1
v = a[:k][0] || 1
Refactorings
No refactoring yet !
David Calavera
July 22, 2008, July 22, 2008 11:15, permalink
1
a ||= {} ; a[:k] ||= []; v = a[:k][0] || 1
Ben Hughes
July 22, 2008, July 22, 2008 11:44, permalink
A little crude, but works...
1
a = a[:k][0] || 1 rescue 1
Markus Prinz
July 22, 2008, July 22, 2008 11:45, permalink
You could also make the default values for the Hash and the Array simply return appropriate objects. But depending on how the rest of your program looks, this could have unintended side-consequences.
1 2 3 4
a = Hash.new{|h,k| h[k] = Array.new { nil } } a[:k] # => [] a[:k][0] # => nil
lel
July 22, 2008, July 22, 2008 14:15, permalink
The above Hash.new can be made prettier. (edit: The reply below is correct, I was so into usage like Hash.new(0) -- where the default object isn't directly modified, unlike an array which often is)
1 2 3 4 5 6
a ||= Hash.new([]) # default value for non-existing keys is now an empty array, unless a was already defined a[:k] # => [] a[:k][0] # => nil v = a[:k][0] || 1
Markus Prinz
July 22, 2008, July 22, 2008 16:34, permalink
Actually you have to be careful with "Hash.new([])", because the hash is going to return that exact same array for every key it doesn't already store. So you should still use the Hash.new with a block. The Array.new isn't necessary though.
1 2 3 4 5 6 7 8 9
h = Hash.new([]) h[:a].object_id # => 9762120 h[:b].object_id # => 9762120 h[:a] << "test" # => ["test"] h[:b] # => ["test"] # Thus: a = Hash.new{|h,k| h[k] = [] } # This ensures that a new Array is generated every time an unknown key is accessed
The problem with this code is that it breaks if a is not defined
And it has undesirable results if a is not an array
Any ideas how to make it more robust without lots of if-then-else?