How do I iterate through the digits of an integer?

32,719

Solution 1

The shortest solution probably is:

1234.to_s.chars.map(&:to_i)
#=> [1, 2, 3, 4]

A more orthodox mathematical approach:

class Integer
  def digits(base: 10)
    quotient, remainder = divmod(base)
    quotient == 0 ? [remainder] : [*quotient.digits(base: base), remainder]
  end
end

0.digits #=> [0]
1234.digits #=> [1, 2, 3, 4]
0x3f.digits(base: 16) #=> [3, 15]

Solution 2

You can use the old trick of modulus/divide by 10, but this won't be measurably faster unless you have huge numbers, and it will give the digits to you backwards:

i = 12345

while i > 0 
  digit = i % 10
  i /= 10
  puts digit
end

Output:

5
4
3
2
1

Solution 3

split=->(x, y=[]) {x < 10 ? y.unshift(x) : split.(x/10, y.unshift(x%10))}

split.(1000) #=> [1,0,0,0]
split.(1234) #=> [1,2,3,4]

Solution 4

Ruby has divmod, which will calculate both x%10and x/10 in one go:

class Integer
  def split_digits
    return [0] if zero?
    res = []
    quotient = self.abs #take care of negative integers
    until quotient.zero? do
      quotient, modulus = quotient.divmod(10) #one go!
      res.unshift(modulus) #put the new value on the first place, shifting all other values
    end
    res # done
  end
end

p 135.split_digits #=>[1, 3, 5]

For things like Project Euler, where speed is of some importance, this is nice to have. Defining it on Integer causes it to be available on Bignum too.

Solution 5

I like Enumerator goodness. I wrote this code for a project of mine:

class Integer
  def digits
    Enumerator.new do |x|
      to_s.chars.map{|c| x << c.to_i }
    end
  end
end

This gives you access to all the good Enumerator stuff:

num = 1234567890

# use each to iterate over the digits
num.digits.each do |digit|
  p digit
end

# make them into an array
p num.digits.to_a     # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

# or take only some digits
p num.digits.take(5)  # => [1, 2, 3, 4, 5]

# you can also use next and rewind
digits = num.digits
p digits.next         # => 1
p digits.next         # => 2
p digits.next         # => 3
digits.rewind
p digits.next         # => 1
Share:
32,719

Related videos on Youtube

Rivasa
Author by

Rivasa

Lowly C++/Java Junior Software Engineer. Answering questions and learning the languages as I navigate the computer science world.

Updated on November 06, 2020

Comments

  • Rivasa
    Rivasa over 3 years

    Possible Duplicate:
    Turning long fixed number to array Ruby

    Well, I have to iterate over the digits of a integer in Ruby. Right now I was just splitting it up into an array, and then iterating over that. However I was wondering if there was a faster way to do this?

    • Alex Peattie
      Alex Peattie over 11 years
      What do you mean by faster? More performant or more concise?
    • robertodecurnex
      robertodecurnex over 11 years
      @link Btw, is it an integer as String or Fixnum ? (1233 or "1233")
    • tokland
      tokland over 11 years
      please show how are you doing it now so we have a reference.
    • Rivasa
      Rivasa over 11 years
      @robertodecurnex, it is a Fixnum, which is converted to an array of strings, which is converted to integers.
    • musicmatze
      musicmatze over 11 years
      That's a very interesting question. The "normal" way would be (as already said in one answer) number.to_s.each_char(&:to_i) or number.to_s.chars.map(&:to_i) . But if you want to have some speed... nice answers in this thread!
  • Linju
    Linju almost 7 years
    To just iterate through the digits, you can also use array slice methods, right? n = 12.to_s sum = (n[0..1].to_i + n[1..2].to_i) product = (n[0,1].to_i * n[1,1].to_i)