web-dev-qa-db-ja.com

整数の数字をどのように反復するのですか?

可能性のある複製:
長い固定数を配列Rubyに変換

まあ、Rubyでは整数の桁を反復処理する必要があります。今、私はそれを配列に分割し、それを繰り返していました。しかし、これを行うためのより速い方法があるかどうか私は思っていましたか?

21
Rivasa

最も短い解決策はおそらく次のとおりです。

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]
43
tokland

10によるモジュラス/除算の古いトリックを使用できますが、これはhugeの数値がない限り、かなり高速ではなく、逆方向に数字を提供します。

i = 12345

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

出力:

5
4
3
2
1
15
meagar
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]
5
robertodecurnex

Rubyには divmod があり、両方を計算しますx%10and 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のように、速度がある程度重要な場合、これは便利です。 Integerで定義すると、Bignumでも使用できるようになります。

4
steenslag

私は列挙子の良さが好きです。私は私のプロジェクトのためにこのコードを書きました:

class Integer
  def digits
    Enumerator.new do |x|
      to_s.chars.map{|c| x << c.to_i }
    end
  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]

# 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
3
Patrick Oscity

Modを10で試して(最後の桁が得られます)、次に10で割って(残りの桁が得られます)、最後の桁になるまでこれを繰り返します。もちろん、数字を左から右に移動する場合は、順序を逆にする必要があります。

2
Mohamed Nuur