How do I iterate through the digits of an integer?
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%10
and 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
Related videos on Youtube
Rivasa
Lowly C++/Java Junior Software Engineer. Answering questions and learning the languages as I navigate the computer science world.
Updated on November 06, 2020Comments
-
Rivasa over 3 years
Possible Duplicate:
Turning long fixed number to array RubyWell, 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 over 11 yearsWhat do you mean by faster? More performant or more concise?
-
robertodecurnex over 11 years@link Btw, is it an integer as String or Fixnum ? (1233 or "1233")
-
tokland over 11 yearsplease show how are you doing it now so we have a reference.
-
Rivasa over 11 years@robertodecurnex, it is a Fixnum, which is converted to an array of strings, which is converted to integers.
-
musicmatze over 11 yearsThat's a very interesting question. The "normal" way would be (as already said in one answer)
number.to_s.each_char(&:to_i)
ornumber.to_s.chars.map(&:to_i)
. But if you want to have some speed... nice answers in this thread!
-
-
Linju almost 7 yearsTo 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)