可能是重复问题:
将长的固定数字转换为数组 Ruby
目前,我需要在 Ruby 中迭代整数的各个数字。现在,我只是将它分成一个数组,然后对其进行迭代。但是我想知道是否有更快的方法可以做到这一点?
可能是重复问题:
将长的固定数字转换为数组 Ruby
目前,我需要在 Ruby 中迭代整数的各个数字。现在,我只是将它分成一个数组,然后对其进行迭代。但是我想知道是否有更快的方法可以做到这一点?
最短的解决方案可能是:
1234.to_s.chars.map(&:to_i)
#=> [1, 2, 3, 4]
一种更正统的数学方法:
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]
你可以使用取模/除以10的旧技巧,但是除非你有非常大的数字,否则这并不会明显更快,并且它会反向给出数字:
i = 12345
while i > 0
digit = i % 10
i /= 10
puts digit
end
输出:
5
4
3
2
1
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]
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]
对于像Project Euler这样速度很重要的问题,这是非常有用的。在整数上定义它可以使它在大整数上可用。
我喜欢使用枚举类型来实现这个目的:
class Integer
def digits
to_s.each_char.lazy.map(&:to_i)
end
end
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]
# ...
to_s.chars.each { |c| x << c.to_i }
更符合正统,因为该块执行了副作用? - tokland
number.to_s.each_char(&:to_i)
或number.to_s.chars.map(&:to_i)
。但是,如果你想要一些速度...本主题中的回答也很好! - musicmatze