Riv*_*asa 21 ruby integer loops
可能重复:
将长固定数转换为数组Ruby
好吧,我必须遍历Ruby中的整数数字.现在我只是把它拆分成一个数组,然后迭代它.但是我想知道是否有更快的方法来做到这一点?
tok*_*and 40
最短的解决方案可能是:
1234.to_s.chars.map(&:to_i)
#=> [1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
更正统的数学方法:
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]
Run Code Online (Sandbox Code Playgroud)
mea*_*gar 15
你可以使用模数/除以10的旧技巧,但除非你有大量的数字,否则它的速度不会快得多,它会向你提供倒数:
i = 12345
while i > 0
digit = i % 10
i /= 10
puts digit
end
Run Code Online (Sandbox Code Playgroud)
输出:
5
4
3
2
1
Run Code Online (Sandbox Code Playgroud)
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]
Run Code Online (Sandbox Code Playgroud)
Ruby有divmod,这将同时计算x%10并x/10一气呵成:
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]
Run Code Online (Sandbox Code Playgroud)
对于像 Project Euler 这样的东西,速度很重要,这很好。在 Integer 上定义它会使其在 Bignum 上也可用。
我喜欢使用枚举器来达到此目的:
class Integer
def digits
to_s.each_char.lazy.map(&:to_i)
end
end
Run Code Online (Sandbox Code Playgroud)
这使您可以访问所有好Enumerator东西:
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]
# ...
Run Code Online (Sandbox Code Playgroud)