此外,我如何将其格式化为左侧用零填充的字符串?
要生成数字,请使用表达式“10的10次方”作为rand函数的参数。
rand(10 ** 10)
要在数字前面填充零,您可以使用字符串格式运算符
'%010d' % rand(10 ** 10)
或者字符串的rjust
方法
rand(10 ** 10).to_s.rjust(10,'0')
我想贡献一种我所知道的最简单的解决方案,这是一个相当不错的技巧。
rand.to_s[2..11]
=> "5950281724"
rand
可能会返回一个低至 0.0
的浮点值,导致生成的字符串为 "0"
。如果你想确认,请在 irb
中尝试运行 (0.0).to_s[2..11]
。 - Eliot Sykes这是生成一个包含10个数字的字符串的快速方法:
10.times.map{rand(10)}.join # => "3401487670"
Array.new(10) { rand(10) }
。 - Zachary Wright最直接的答案可能是
rand(1e9...1e10).to_i
需要使用to_i
部分,因为1e9
和1e10
实际上是浮点数:
irb(main)> 1e9.class
=> Float
puts Benchmark.measure{(1..1000000).map{rand(1e9...1e10).to_i}}
实际上,我需要一个字符串作为我的最终结果,但即使在末尾添加.to_s
仍然会产生更快的结果。puts Benchmark.measure{(1..1000000).map{rand(1e9...1e10).to_i.to_s}}
- Steve Meisner10000.times.map{rand(1e9...1e10).to_i.to_s}.select!{|x| x.start_with?("0")}
返回 []。 - Oskar Holmkratzrand.to_s[2..11].to_i
为什么?因为你可能得到以下内容:
rand.to_s[2..9] #=> "04890612"
然后:
"04890612".to_i #=> 4890612
请注意:
4890612.to_s.length #=> 7
这不是你预期的结果!
为了检查你自己代码中的错误,你可以用下面的方式进行包装,而不是使用.to_i
:
Integer(rand.to_s[2..9])
很快就会变成:
ArgumentError: invalid value for Integer(): "02939053"
所以最好坚持使用.center
,但要记住:
rand(9)
有时可能会给你0
。
为了防止这种情况:
rand(1..9)
这个函数将始终返回 1..9
范围内的某个值。
我很高兴我的测试效果不错,希望你也能避免破坏你的系统。
使用Kernel#rand方法:
rand(1_000_000_000..9_999_999_999) # => random 10-digits number
使用 times
+ map
+ join
组合:
10.times.map { rand(0..9) }.join # => random 10-digit string (may start with 0!)
使用String#%方法:
"%010d" % 123348 # => "0000123348"
使用 KeePass 密码生成器 库,它支持不同的模式来生成随机密码:
KeePass::Password.generate("d{10}") # => random 10-digit string (may start with 0!)
可以在这里找到KeePass模式的文档。
Kernel#sprintf
方法(或它在Powerpack库中的别名Kernel#format
),而非String#%
方法。这也被提到了Ruby Community Style Guide。# considered bad
'%010d' % rand(10**10)
# considered good
sprintf('%010d', rand(10**10))
这种偏好的本质主要是由于百分号%
的神秘性质。它本身并不具有很强的语义,如果没有任何额外的上下文,它可能会被误解为%
取模运算符。
样式指南中的示例:
# bad
'%d %d' % [20, 10]
# => '20 10'
# good
sprintf('%d %d', 20, 10)
# => '20 10'
# good
sprintf('%{first} %{second}', first: 20, second: 10)
# => '20 10'
format('%d %d', 20, 10)
# => '20 10'
# good
format('%{first} %{second}', first: 20, second: 10)
# => '20 10'
String#%
的作用,我个人更喜欢使用操作符式的语法而非命令式的语法,就像你会使用your_array << 'foo'
而非your_array.push('123')
一样。这里有一个表达式,它将比quackingduck的示例少使用一个方法调用。
'%011d' % rand(1e10)
需要注意的是,1e10
是一个 Float
类型,而 Kernel#rand
函数会将其转换为整数类型 to_i
,所以对于一些较大的值可能会出现不一致的情况。如果要更加精确地使用字面量,也可以这样做:
'%011d' % rand(10_000_000_000) # Note that underscores are ignored in integer literals
('%010d' % rand(0..9999999999)).to_s
或者
"#{'%010d' % rand(0..9999999999)}"
0000000000
。有没有什么方法可以防止这种情况发生? - Tintin81