2012-01-16 3 views
5

임의의 크기의 해시를 가지고 있는데, 정수로 변환하고자하는 "100" 같은 값이있을 수 있습니다. 나는 value.to_i if value.to_i.to_s == value을 사용하여이 작업을 수행 할 수 있음을 알고 있지만 값이 문자열 또는 해시 또는 문자열 배열 또는 다른 해시 일 수 있다는 점을 감안할 때 재귀 적으로 해시를 반복적으로 수행하는 방법을 잘 모르겠습니다.모든 숫자 문자열을 루비 해시의 정수로 재귀 적으로 변환합니다.

+0

포스트는 예를 –

+0

또한, 귀하의 질문에 대답 : 사용 재귀를 #is_kind_of'와' –

+0

'obj.to_i.to_s == obj' 이상한 것 같다?. 동일한 정수 값에 대해 서로 다른 문자열 표현이있을 수 있습니다 (예 : "1_000_000"또는 "019". –

답변

10

이것은 매우 간단한 재귀 구현입니다 (배열과 해시를 모두 처리하면 약간의 까다 롭습니다).

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=>{}} 
+1

고마워, 그거야. 그러나 첫 번째 if를 if obj.respond_to로 변경해야했습니다. : to_i 및 obj.to_i.to_s == obj' 내 해시에는 영문자 문자열도 포함될 수 있기 때문에. 그에 따라 응답을 편집 할 수 있습니다. 다시 한 번 감사드립니다! –

+2

'obj.merge (obj) {| k, val | fixnumify val}'=>'해쉬 [obj.map {| k, v | [k, fixnumify (val)]'? 직감이 더 빨라질 수 있습니다. –

+0

그럴 수 있습니다, @ VictorMoroz, 비록 내가 점차적으로 추측합니다. 나는 항상 '해시 (Hash)'를 잊어 버린다. 감사! –

0

이 내 도우미 클래스입니다. 그냥 정수 (Integer 또는 Float) 인 문자열 만 변환합니다.

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"}]] 
관련 문제