Turning long fixed number to array Ruby

前端 未结 7 671
我寻月下人不归
我寻月下人不归 2020-12-03 22:43

Is there a method in ruby to turn fixnum like 74239 into an array like [7,4,2,3,9]?

相关标签:
7条回答
  • 2020-12-03 22:54

    In Ruby 2.4, integers will have a digits method.

    0 讨论(0)
  • 2020-12-03 22:56

    You can also use Array.new instead of map:

    n = 74239
    
    s = Math.log10(n).to_i + 1 # Gets the size of n
    
    Array.new(s) { d = n % 10; n = n / 10; d }.reverse 
    
    0 讨论(0)
  • 2020-12-03 22:59

    Maybe not the most elegant solution:

    74239.to_s.split('').map(&:to_i)
    

    Output:

    [7, 4, 2, 3, 9]
    
    0 讨论(0)
  • 2020-12-03 23:01

    The divmod method can be used to extract the digits one at a time

    def digits n
      n= n.abs
      [].tap do |result|
        while n > 0 
          n,digit = n.divmod 10
          result.unshift digit
        end
      end
    end
    

    A quick benchmark showed this to be faster than using log to find the number of digits ahead of time, which was itself faster than string based methods.

    bmbm(5) do |x|
      x.report('string') {10000.times {digits_s(rand(1000000000))}}
      x.report('divmod') {10000.times {digits_divmod(rand(1000000000))}}
      x.report('log') {10000.times {digits(rand(1000000000))}}
    end
    
    #=>
                 user     system      total        real
    string   0.120000   0.000000   0.120000 (  0.126119)
    divmod   0.030000   0.000000   0.030000 (  0.023148)
    log      0.040000   0.000000   0.040000 (  0.045285)
    
    0 讨论(0)
  • 2020-12-03 23:02

    As of Ruby 2.4, integers (FixNum is gone in 2.4+) have a built-in digits method that extracts them into an array of their digits:

    74239.digits
    => [9, 3, 2, 4, 7]
    

    If you want to maintain the order of the digits, just chain reverse:

    74239.digits.reverse
    => [7, 4, 2, 3, 9]
    

    Docs: https://ruby-doc.org/core-2.4.0/Integer.html#method-i-digits

    0 讨论(0)
  • 2020-12-03 23:09

    You don't need to take a round trip through string-land for this sort of thing:

    def digits(n)
      Math.log10(n).floor.downto(0).map { |i| (n / 10**i) % 10 }
    end
    
    ary = digits(74239)
    # [7, 4, 2, 3, 9]
    

    This does assume that n is positive of course, slipping an n = n.abs into the mix can take care of that if needed. If you need to cover non-positive values, then:

    def digits(n)
      return [0] if(n == 0)
      if(n < 0)
        neg = true
        n   = n.abs
      end
      a = Math.log10(n).floor.downto(0).map { |i| (n / 10**i) % 10 }
      a[0] *= -1 if(neg)
      a
    end
    
    0 讨论(0)
提交回复
热议问题