2012-01-16 35 views
5

Tôi có một giá trị băm ngẫu nhiên, có thể có các giá trị như "100", mà tôi muốn chuyển đổi thành số nguyên. Tôi biết tôi có thể làm điều này bằng cách sử dụng value.to_i if value.to_i.to_s == value, nhưng tôi không chắc chắn làm thế nào tôi sẽ làm điều đó đệ quy trong băm của tôi, xem xét rằng một giá trị có thể là một chuỗi, hoặc một mảng (của băm hoặc chuỗi), hoặc băm khác.Chuyển đổi đệ quy tất cả chuỗi số thành số nguyên trong mã băm Ruby

+0

bài viết một ví dụ –

+0

Ngoài ra, câu trả lời cho câu hỏi của bạn: sử dụng đệ quy với '#is_kind_of ' –

+0

' obj.to_i.to_s == obj' có vẻ kỳ lạ?. Có thể có các biểu diễn chuỗi khác nhau cho cùng một giá trị số nguyên, ví dụ: "1_000_000" hoặc "019". –

Trả lời

10

Đây là một triển khai đệ quy khá đơn giản (mặc dù phải xử lý cả mảng và băm bổ sung thêm một chút khéo léo).

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 

Và, hey, nó thậm chí hoạt động:

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

Cảm ơn, điều đó hoạt động. Tuy nhiên, tôi phải thay đổi đầu tiên nếu thành 'if obj.respond_to? : to_i và obj.to_i.to_s == obj' vì băm của tôi cũng có thể chứa các chuỗi chữ cái. Bạn có thể chỉnh sửa câu trả lời cho phù hợp. Cảm ơn một lần nữa! –

+2

'obj.merge (obj) {| k, val | fixnumify val} '=>' Hash [obj.map {| k, v | [k, fixnumify (val)] '? Chỉ cần có linh cảm thì nó có thể nhanh hơn. –

+0

Đó có thể là, @VictorMoroz, mặc dù tôi chỉ đoán từng bước một. Tôi luôn luôn quên về 'Hash []'. Cảm ơn! –

0

Đây là lớp helper của tôi. Nó chỉ chuyển đổi các chuỗi chỉ là số (Integer hoặc 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"}]] 
Các vấn đề liên quan