def [](key, add_on=nil)
      case key
        when /\A(\d{4})(\d\d)\z/
          by_code_and_add_on($1.to_i, $2.to_i)
        when 100_000..999_999
          by_code_and_add_on(*key.divmod(100))
        when 0..9999, /\A\d{4}\z/
          case add_on
            when nil
              by_code(key.to_i)
            when 0..99, /\A\d+\z/
              by_code_and_add_on(key.to_i, add_on.to_i)
            when String
              by_code_and_name(key.to_i, add_on)
            else
              raise ArgumentError,
                    "Expected a String, an Integer between 0 and 99, or a String containing an integer between 0 and 99, " \
                    "but got #{key.class}: #{key.inspect}"
          end
        when String
          by_name(key)
        else
          raise ArgumentError,
                "Expected a String, an Integer between 1000 and 9999, or an " \
                "Integer between 100_000 and 999_999, but got #{key.class}:" \
                "#{key.inspect}"
      end
    end
def [](key, add_on=nil)
      case key
        when /\A(\d{4})(\d\d)\z/
          by_code_and_add_on($1.to_i, $2.to_i)
        when 100_000..999_999
          by_code_and_add_on(*key.divmod(100))
        when 0..9999, /\A\d{4}\z/
          case add_on
            when nil
              by_code(key.to_i)
            when 0..99, /\A\d+\z/
              by_code_and_add_on(key.to_i, add_on.to_i)
            when String
              by_code_and_name(key.to_i, add_on)
            else
              raise ArgumentError,
                    "Expected a String, an Integer between 0 and 99, or a String containing an integer between 0 and 99, " \
                    "but got #{key.class}: #{key.inspect}"
          end
        when String
          by_name(key)
        else
          raise ArgumentError,
                "Expected a String, an Integer between 1000 and 9999, or an " \
                "Integer between 100_000 and 999_999, but got #{key.class}:" \
                "#{key.inspect}"
      end
    end
A convenience method to get one or many zip codes by code, code and add-on, code and city or just
 city.
 There are various allowed styles to pass those values.
 All numeric values can be passed either as Integer or String.
 You can pass the code and add-on as six-digit number, or you can pass the code
 as four digit number plus either the add-on or name as second parameter. Or you can
 pass the code alone, or the name alone.

 @example All usage styles
   zip_codes[805200]           # zip code 8052, add-on 0
   zip_codes["805200"]         # zip code 8052, add-on 0
   zip_codes[8052, 0]          # zip code 8052, add-on 0
   zip_codes["8052", 0]        # zip code 8052, add-on 0
   zip_codes[8052, "0"]        # zip code 8052, add-on 0
   zip_codes["8052", 0]        # zip code 8052, add-on 0
   zip_codes[8052, "Zürich"]   # zip code 8052, add-on 0
   zip_codes["8052", "Zürich"] # zip code 8052, add-on 0
   zip_codes[8052]             # all zip codes with code 8052
   zip_codes["8052"]           # all zip codes with code 8052
   zip_codes["Zürich"]         # all zip codes with name "Zürich"

 @see #by_code_and_add_on  Get a zip code by code and add-on directly
 @see #by_code_and_name    Get a zip code by code and name directly
 @see #by_name             Get a collection of zip codes by name directly
 @see #by_ordering_number  Get a zip code by its ONRP directly (#[] can't do that)

 @param [String, Integer] key
   Either the zip code, zip code and add-on
 @return [SwissMatch::ZipCode, SwissMatch::ZipCodes]
   Either a SwissMatch::ZipCodes collection of zip codes or a single SwissMatch::ZipCode, depending on
   the argument you pass.