I was doing some hacking with lists of valid phone number codes (3,4,5 digits depending upon various factors). I used hashes that could be walked down because of the key lengths. Now we've decided to do it differently because the data file wasn't up to date ...
This gets the phone number as an array of integers:
code_pieces = code.to_s.split(//).collect(&:to_i) rescue []
(note the Rails &: thing)
This takes a list of keys and a value, pops the value off the beginning of the array and when the array is done then puts the value in with a hash key of -1:
def hash_for_digits(n_array,value)
n = n_array.delete_at(0)
if n
the_hash = {}
the_hash.merge({ n => hash_for_digits(n_array,value) })
else
{ -1 => value}
end
end
This is a merge of a hash of hashes with another - warning - it blows up without the -1 markers from the previous function.
def deep_merge_hash(hash1,hash2)
hash2.each_key do |k1|
if hash1.key?(k1)
deep_merge_hash(hash1[k1],hash2[k1])
else
hash1[k1] = hash2[k1]
end
end
end
Hope others find this some use - I might return to this another day and make it work with arbitrary hashes but now too busy and didn't want to throw the code away ...
The return from the function looked like this:
top_number = get_code_ref[code_pieces[0]][code_pieces[1]][code_pieces[2]] rescue nil
if top_number
ok = top_number[code_pieces[3]][code_pieces[4]][-1] rescue nil
ok = top_number[code_pieces[3]][-1] unless ok rescue nil
ok = top_number[-1] unless ok rescue nil
end
ok
I realised I could probably have speeded things up by having the first 3 as a hash key in their own right but too late now - reimplementation with a different data set on the way ...