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 was’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 did’t want to throw the code away … 

The return from the function looked like this:

      top_number = get_code_ref[code_pieces0][code_pieces1][code_pieces2] rescue nil
      if top_number
        ok = top_number[code_pieces3][code_pieces4][-1] rescue nil
        ok = top_number[code_pieces3][-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 …