Рекурсивно преобразовать все числовые строки в целые числа в хэше Ruby - PullRequest
5 голосов
/ 16 января 2012

У меня есть хэш случайного размера, который может иметь значения типа "100", которые я хотел бы преобразовать в целые числа. Я знаю, что могу сделать это, используя value.to_i if value.to_i.to_s == value, но я не уверен, как мне сделать это рекурсивно в моем хэше, учитывая, что значение может быть либо строкой, либо массивом (из хэшей или строк), либо другим хэш.

Ответы [ 2 ]

10 голосов
/ 16 января 2012

Это довольно простая рекурсивная реализация (хотя обработка массивов и хэшей добавляет немного хитрости).

def fixnumify obj
  if obj.respond_to? :to_i
    # If we can cast it to a Fixnum, do it.
    obj.to_i

  elsif obj.is_a? Array
    # If it's an Array, use Enumerable#map to recursively call this method
    # on each item.
    obj.map {|item| fixnumify item }

  elsif obj.is_a? Hash
    # If it's a Hash, recursively call this method on each value.
    obj.merge( obj ) {|k, val| fixnumify val }

  else
    # If for some reason we run into something else, just return
    # it unmodified; alternatively you could throw an exception.
    obj

  end
end

И, эй, это даже работает:

hsh = { :a => '1',
        :b => '2',
        :c => { :d => '3',
                :e => [ 4, '5', { :f => '6' } ]
              },
        :g => 7,
        :h => [],
        :i => {}
      }

fixnumify hsh
# => {:a=>1, :b=>2, :c=>{:d=>3, :e=>[4, 5, {:f=>6}]}, :g=>7, :h=>[], :i=>{}}
0 голосов
/ 18 ноября 2016

Это мой вспомогательный класс.Он преобразует только те строки, которые являются просто числами (целые или с плавающей точкой).

module Helpers
  class Number
    class << self
      def convert(object)
        case object
        when String
          begin
            numeric(object)
          rescue StandardError
            object
          end
        when Array
          object.map { |i| convert i }
        when Hash
          object.merge(object) { |_k, v| convert v }
        else
          object
        end
      end # convert

      private

      def numeric(object)
        Integer(object)
      rescue
        Float(object)
      end # numeric
   end # << self
  end # Number
end # Helpers

Helpers::Number.convert [{a: ["1", "22sd"]}, 2, ['1.3', {b: "c"}]]
#=> [{:a=>[1, "22sd"]}, 2, [1.3, {:b=>"c"}]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...