在 Ruby 中将整数格式化为固定长度的字符串

Format integer to string with fixed length in Ruby

有没有一种简单的方法可以将给定的整数格式化为具有固定长度和前导零的字符串?

# convert numbers to strings of fixed length 3 
[1, 12, 123, 1234].map { |e| ??? }
=> ["001", "012", "123", "234"]

我找到了解决方案,但也许还有更聪明的方法。

format('%03d', e)[-3..-1]

如何使用 % 1000 而不是进行字符串操作来获取最后三位数字?

[1, 12, 123, 1234].map { |e| format('%03d', e % 1000) }

更新:

正如 the Tin Man 在评论中所建议的那样,原始版本在可读性方面更好,只比这个慢 1.05 倍,所以在大多数情况下使用它可能是有意义的。

[1, 12, 123, 1234].map { |e| ("%03d" % e)[/...$/] }

您可以将模数除法 %String#% 方法结合使用。 (您不需要 format-命令):

[1, 12, 123, 1234].map { |e| "%03d" % (e % 1000)}

用一些标记来解释不同%:

[1, 12, 123, 1234].map { |e| "%03d" % (e % 1000)}
#                            (1)   (2)   (3)
  • (1): 格式规范,3 个带前导零的数字。
  • (2): String#%-方法
  • (3):整数的模除法

您在 的评论中提到: 格式化字符串和除数之间还有这种dependency/duplication

您可以定义变量中的位数并在格式字符串和除数中使用它:

digits = 3
[1, 12, 123, 1234].map { |e| "%0*d" % [digits,e % 10**digits]}

您可以使用 String#rjust。它使用给定的填充字符向右填充(右对齐)字符串,使其成为给定的长度。

[1, 12, 123, 1234].map { |e| e.to_s.rjust(3,'0')[-3..-1]}

基准:

require 'fruity'

VALUES = (1..9999).to_a.shuffle.take(100)

5.times do
  compare do
    original { VALUES.map { |e| format('%03d', e)[-3..-1] } }
    w0lf     { VALUES.map { |e| format('%03d', e % 1000) } }
    owade    { VALUES.map { |e| e.to_s.rjust(3,'0')[-3..-1]} }
    sdayal   { VALUES.map { |e| ("%03d" % e)[/...$/] } }
  end
  puts
end
# >> Running each test 64 times. Test will take about 1 second.
# >> owade is similar to w0lf
# >> w0lf is faster than original by 39.99999999999999% ± 10.0%
# >> original is faster than sdayal by 2x ± 0.1
# >> 
# >> Running each test 64 times. Test will take about 1 second.
# >> owade is similar to w0lf
# >> w0lf is similar to original
# >> original is faster than sdayal by 2x ± 0.1
# >> 
# >> Running each test 64 times. Test will take about 1 second.
# >> owade is similar to w0lf
# >> w0lf is similar to original
# >> original is faster than sdayal by 2x ± 1.0
# >> 
# >> Running each test 64 times. Test will take about 1 second.
# >> owade is similar to w0lf
# >> w0lf is similar to original
# >> original is faster than sdayal by 2x ± 1.0
# >> 
# >> Running each test 64 times. Test will take about 1 second.
# >> owade is similar to w0lf
# >> w0lf is similar to original
# >> original is faster than sdayal by 2x ± 0.1
# >> 

我使用了五次迭代,因为结果不稳定。可能是因为我的机器上现在有一个备份 运行,影响了处理。要点是一致的,即使用正则表达式获取最后三个值不是可行的方法。虽然对于单个阵列来说,不同的执行方式之间的差异可能并不显着,但重复该过程数千次,它可以累加起来。